internal class AnyOrderComparer<T> : IEqualityComparer<IEnumerable<T>>
where T : IEquatable<T>
{
- public static readonly AnyOrderComparer<T> Instance = new AnyOrderComparer<T>();
+ public static readonly AnyOrderComparer<T> Instance = new();
public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
{
{
public class ApiLimitTest
{
- public static readonly TheoryData<object?, bool> EqualsTestCase = new TheoryData<object?, bool>
+ public static readonly TheoryData<object?, bool> EqualsTestCase = new()
{
{ new ApiLimit(150, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), true },
{ new ApiLimit(350, 100, new DateTimeUtc(2013, 1, 1, 0, 0, 0)), false },
Assert.Equal(TwitterApiAccessLevel.Anonymous, apiStatus.AccessLevel);
}
- public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseRateLimitTestCase = new TheoryData<Dictionary<string, string>, ApiLimit?>
+ public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseRateLimitTestCase = new()
{
{
new Dictionary<string, string>
Assert.Equal(expected, limit);
}
- public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseMediaRateLimitTestCase = new TheoryData<Dictionary<string, string>, ApiLimit?>
+ public static readonly TheoryData<Dictionary<string, string>, ApiLimit?> ParseMediaRateLimitTestCase = new()
{
{
new Dictionary<string, string>
Assert.Equal(expected, limit);
}
- public static readonly TheoryData<Dictionary<string, string>, TwitterApiAccessLevel?> ParseAccessLevelTestCase = new TheoryData<Dictionary<string, string>, TwitterApiAccessLevel?>
+ public static readonly TheoryData<Dictionary<string, string>, TwitterApiAccessLevel?> ParseAccessLevelTestCase = new()
{
{
new Dictionary<string, string> { { "X-Access-Level", "read" } },
utc.ToDateTimeUnsafe());
}
- public static readonly TheoryData<string, DateTimeUtc> ParseTestFixtures = new TheoryData<string, DateTimeUtc>
+ public static readonly TheoryData<string, DateTimeUtc> ParseTestFixtures = new()
{
{ "2018-05-06T11:22:33.111", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
{ "2018-05-06T11:22:33.111+00:00", new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
public void Parse_ErrorTest()
=> Assert.Throws<FormatException>(() => DateTimeUtc.Parse("### INVALID ###", DateTimeFormatInfo.InvariantInfo));
- public static readonly TheoryData<string, bool, DateTimeUtc> TryParseTestFixtures = new TheoryData<string, bool, DateTimeUtc>
+ public static readonly TheoryData<string, bool, DateTimeUtc> TryParseTestFixtures = new()
{
{ "2018-05-06T11:22:33.111", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
{ "2018-05-06T11:22:33.111+00:00", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
Assert.Equal(expectedResult, result);
}
- public static readonly TheoryData<string, string, bool, DateTimeUtc> TryParseExactTestFixtures = new TheoryData<string, string, bool, DateTimeUtc>
+ public static readonly TheoryData<string, string, bool, DateTimeUtc> TryParseExactTestFixtures = new()
{
{ "2018-05-06 11:22:33.111", "yyyy-MM-dd HH:mm:ss.fff", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
{ "2018-05-06 11:22:33.111 +00:00", "yyyy-MM-dd HH:mm:ss.fff zzz", true, new DateTimeUtc(2018, 5, 6, 11, 22, 33, 111) },
{
private class TestDebounceTimer : DebounceTimer
{
- public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask);
+ public MockTimer MockTimer = new(() => Task.CompletedTask);
public TestDebounceTimer(Func<Task> timerCallback, TimeSpan interval, bool leading, bool trailing)
: base(timerCallback, interval, leading, trailing)
public class HttpMessageHandlerMock : HttpMessageHandler
{
private readonly Queue<Func<HttpRequestMessage, Task<HttpResponseMessage>>> queue =
- new Queue<Func<HttpRequestMessage, Task<HttpResponseMessage>>>();
+ new();
public int QueueCount
=> this.queue.Count;
private class FakeExpandedUrlInfo : PostClass.ExpandedUrlInfo
{
- public TaskCompletionSource<string> FakeResult = new TaskCompletionSource<string>();
+ public TaskCompletionSource<string> FakeResult = new();
public FakeExpandedUrlInfo(string url, string expandedUrl, bool deepExpand)
: base(url, expandedUrl, deepExpand)
public void IsAnimatedGifTest(string filename, bool expected)
=> Assert.Equal(expected, MyCommon.IsAnimatedGif(filename));
- public static readonly TheoryData<string, DateTimeUtc> DateTimeParseTestCase = new TheoryData<string, DateTimeUtc>
+ public static readonly TheoryData<string, DateTimeUtc> DateTimeParseTestCase = new()
{
{ "Sun Nov 25 06:10:00 +00:00 2012", new DateTimeUtc(2012, 11, 25, 6, 10, 0) },
{ "Sun, 25 Nov 2012 06:10:00 +00:00", new DateTimeUtc(2012, 11, 25, 6, 10, 0) },
public string Body { get; set; }
}
- public static readonly TheoryData<string, JsonData> CreateDataFromJsonTestCase = new TheoryData<string, JsonData>
+ public static readonly TheoryData<string, JsonData> CreateDataFromJsonTestCase = new()
{
{
@"{""id"":""1"", ""body"":""hogehoge""}",
public void GetReadableVersionTest(string fileVersion, string expected)
=> Assert.Equal(expected, MyCommon.GetReadableVersion(fileVersion));
- public static readonly TheoryData<PostClass, string> GetStatusUrlTest1TestCase = new TheoryData<PostClass, string>
+ public static readonly TheoryData<PostClass, string> GetStatusUrlTest1TestCase = new()
{
{
new PostClass { StatusId = 249493863826350080L, ScreenName = "Favstar_LM", RetweetedId = null, RetweetedBy = null },
}
public static MemoryImageMediaItem CreateDummyMediaItem()
- => new MemoryImageMediaItem(CreateDummyImage());
+ => new(CreateDummyImage());
public static void FireEvent<T>(T control, string eventName)
where T : Control
{
private class TestThrottleTimer : ThrottleTimer
{
- public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask);
+ public MockTimer MockTimer = new(() => Task.CompletedTask);
public TestThrottleTimer(Func<Task> timerCallback, TimeSpan interval)
: base(timerCallback, interval)
{
private class TestTimelineScheduler : TimelineScheduler
{
- public MockTimer MockTimer = new MockTimer(() => Task.CompletedTask);
+ public MockTimer MockTimer = new(() => Task.CompletedTask);
public TestTimelineScheduler()
: base()
{
public class BitlyApi
{
- public static readonly Uri ApiBase = new Uri("https://api-ssl.bitly.com/");
+ public static readonly Uri ApiBase = new("https://api-ssl.bitly.com/");
public string EndUserAccessToken { get; set; } = "";
=> this.Status = status;
public static StreamMessageStatus ParseJson(string json)
- => new StreamMessageStatus(TwitterStatusCompat.ParseJson(json));
+ => new(TwitterStatusCompat.ParseJson(json));
}
public class StreamMessageKeepAlive : ITwitterStreamMessage
private readonly ApiKey clientId;
private readonly HttpClient http;
- public static readonly Uri UploadEndpoint = new Uri("https://api.imgur.com/3/image.xml");
+ public static readonly Uri UploadEndpoint = new("https://api.imgur.com/3/image.xml");
public ImgurApi()
: this(ApplicationSettings.ImgurClientId, null)
{
public class MicrosoftTranslatorApi
{
- public static readonly Uri IssueTokenEndpoint = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
- public static readonly Uri TranslateEndpoint = new Uri("https://api.cognitive.microsofttranslator.com/translate");
+ public static readonly Uri IssueTokenEndpoint = new("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
+ public static readonly Uri TranslateEndpoint = new("https://api.cognitive.microsofttranslator.com/translate");
public string AccessToken { get; internal set; } = "";
private readonly ApiKey apiKey;
private readonly HttpClient http;
- public static readonly Uri UploadEndpoint = new Uri("https://api.mobypicture.com/2.0/upload.xml");
+ public static readonly Uri UploadEndpoint = new("https://api.mobypicture.com/2.0/upload.xml");
- private static readonly Uri OAuthRealm = new Uri("http://api.twitter.com/");
- private static readonly Uri AuthServiceProvider = new Uri("https://api.twitter.com/1.1/account/verify_credentials.json");
+ private static readonly Uri OAuthRealm = new("http://api.twitter.com/");
+ private static readonly Uri AuthServiceProvider = new("https://api.twitter.com/1.1/account/verify_credentials.json");
public MobypictureApi(TwitterApi twitterApi)
: this(ApplicationSettings.MobypictureKey, twitterApi)
}
public static TwitterApiException CreateFromException(HttpRequestException ex)
- => new TwitterApiException(ex.InnerException?.Message ?? ex.Message, ex);
+ => new(ex.InnerException?.Message ?? ex.Message, ex);
public static TwitterApiException CreateFromException(OperationCanceledException ex)
- => new TwitterApiException("Timeout", ex);
+ => new("Timeout", ex);
public static TwitterApiException CreateFromException(SerializationException ex, string responseText)
- => new TwitterApiException("Invalid JSON", responseText, ex);
+ => new("Invalid JSON", responseText, ex);
private static string FormatTwitterError(TwitterError error)
=> string.Join(",", error.Errors.Select(x => x.ToString()));
public TwitterApiStatus Owner { get; }
private readonly ConcurrentDictionary<string, ApiLimit> innerDict
- = new ConcurrentDictionary<string, ApiLimit>();
+ = new();
public EndpointLimits(TwitterApiStatus owner)
=> this.Owner = owner;
public ApiInfoDialog()
=> this.InitializeComponent();
- private readonly List<string> tlEndpoints = new List<string>
+ private readonly List<string> tlEndpoints = new()
{
"/statuses/home_timeline",
"/statuses/mentions_timeline",
/// <see cref="ApiKey"/> インスタンスを作成します
/// </summary>
public static ApiKey Create(string password, string rawKey)
- => new ApiKey(password, rawKey);
+ => new(password, rawKey);
/// <summary>
/// 指定された文字列を暗号化して返します
public bool Lists;
public bool UserTimeline;
- public static IntervalChangedEventArgs ResetAll => new IntervalChangedEventArgs
+ public static IntervalChangedEventArgs ResetAll => new()
{
Timeline = true,
Reply = true,
{
public class Bing
{
- private static readonly List<string> LanguageTable = new List<string>
+ private static readonly List<string> LanguageTable = new()
{
"af",
"sq",
public static class LazyJson
{
public static LazyJson<T> Create<T>(T instance)
- => new LazyJson<T>(instance);
+ => new(instance);
}
public static class LazyJsonTaskExtension
/// <summary>
/// OAuth署名のoauth_nonce算出用乱数クラス
/// </summary>
- private static readonly Random NonceRandom = new Random();
+ private static readonly Random NonceRandom = new();
/// <summary>
/// HTTPリクエストに追加するAuthorizationヘッダの値を生成します
{
public class TwitterApiConnection : IApiConnection, IDisposable
{
- public static Uri RestApiBase { get; set; } = new Uri("https://api.twitter.com/1.1/");
+ public static Uri RestApiBase { get; set; } = new("https://api.twitter.com/1.1/");
// SettingCommon.xml の TwitterUrl との互換性のために用意
public static string RestApiHost
=> (long)(this - UnixEpoch).TotalSeconds;
public DateTimeOffset ToDateTimeOffset()
- => new DateTimeOffset(this.datetime);
+ => new(this.datetime);
public DateTimeOffset ToLocalTime()
=> this.ToDateTimeOffset().ToLocalTime();
=> this.ToLocalTime().ToString(format);
public static DateTimeUtc operator +(DateTimeUtc a, TimeSpan b)
- => new DateTimeUtc(a.datetime + b);
+ => new(a.datetime + b);
public static DateTimeUtc operator -(DateTimeUtc a, TimeSpan b)
- => new DateTimeUtc(a.datetime - b);
+ => new(a.datetime - b);
public static TimeSpan operator -(DateTimeUtc a, DateTimeUtc b)
=> a.datetime - b.datetime;
=> UnixEpoch + TimeSpan.FromTicks(unixTime * TimeSpan.TicksPerSecond);
public static DateTimeUtc Parse(string input, IFormatProvider formatProvider)
- => new DateTimeUtc(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal));
+ => new(DateTimeOffset.Parse(input, formatProvider, DateTimeStyles.AssumeUniversal));
public static bool TryParse(string input, IFormatProvider formatProvider, out DateTimeUtc result)
{
{
private readonly ITimer debouncingTimer;
private readonly Func<Task> timerCallback;
- private readonly object lockObject = new object();
+ private readonly object lockObject = new();
private DateTimeUtc lastCall;
private bool calledSinceLastInvoke;
=> this.debouncingTimer.Dispose();
public static DebounceTimer Create(Func<Task> callback, TimeSpan wait, bool leading = false, bool trailing = true)
- => new DebounceTimer(callback, wait, leading, trailing);
+ => new(callback, wait, leading, trailing);
}
}
}
public static ReadLockTransaction BeginReadTransaction(this ReaderWriterLockSlim lockObj)
- => new ReadLockTransaction(lockObj);
+ => new(lockObj);
public static WriteLockTransaction BeginWriteTransaction(this ReaderWriterLockSlim lockObj)
- => new WriteLockTransaction(lockObj);
+ => new(lockObj);
public static UpgradeableReadLockTransaction BeginUpgradeableReadTransaction(this ReaderWriterLockSlim lockObj)
- => new UpgradeableReadLockTransaction(lockObj);
+ => new(lockObj);
/// <summary>
/// 一方のカルチャがもう一方のカルチャを内包するかを判断します
private class ForEachObserver<T> : IObserver<T>
{
private readonly Func<T, Task> subscriber;
- private readonly TaskCompletionSource<int> tcs = new TaskCompletionSource<int>();
+ private readonly TaskCompletionSource<int> tcs = new();
public Task Task
=> this.tcs.Task;
private MultiSelectionState multiSelState = MultiSelectionState.None;
private readonly TabInformations sts;
- private List<TabModel> tabs = new List<TabModel>();
+ private List<TabModel> tabs = new();
private int selectedTabIndex = -1;
- private readonly List<string> idlist = new List<string>();
+ private readonly List<string> idlist = new();
private enum EDITMODE
{
/// <summary>
/// innerDictionary の排他制御のためのロックオブジェクト
/// </summary>
- private readonly object lockObject = new object();
+ private readonly object lockObject = new();
/// <summary>
/// オブジェクトが破棄された否か
/// </remarks>
public int StateIndex { get; set; }
- private readonly WeakReference imageReference = new WeakReference(null);
+ private readonly WeakReference imageReference = new(null);
private Task? imageTask = null;
public event EventHandler? ImageDownloaded;
ALLOW_SCRIPT = 0x2,
}
- private readonly object ocx = new object();
+ private readonly object ocx = new();
private readonly WebBrowserAPI.IServiceProvider ocxServiceProvider;
- private readonly IntPtr profferServicePtr = new IntPtr();
+ private readonly IntPtr profferServicePtr = new();
private readonly WebBrowserAPI.IProfferService profferService = null!;
public POLICY SecurityPolicy { get; set; } = 0;
// ----------------------------------------------------------------------
// ここ以下は COM Interface の宣言です。
- public static Guid IID_IProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0");
- public static Guid SID_SProfferService = new Guid("cb728b20-f786-11ce-92ad-00aa00a74cd0");
- public static Guid IID_IInternetSecurityManager = new Guid("79eac9ee-baf9-11ce-8c82-00aa004ba90b");
+ public static Guid IID_IProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0");
+ public static Guid SID_SProfferService = new("cb728b20-f786-11ce-92ad-00aa00a74cd0");
+ public static Guid IID_IInternetSecurityManager = new("79eac9ee-baf9-11ce-8c82-00aa004ba90b");
[ComImport]
[Guid("6d5140c1-7436-11ce-8034-00aa006009fa")]
protected Twitter tw = null!;
- private List<UserInfo> members = new List<UserInfo>();
+ private List<UserInfo> members = new();
[XmlIgnore]
public long Cursor { get; private set; } = -1;
=> this.Text;
}
- private Dictionary<string, IMediaUploadService> pictureService = new Dictionary<string, IMediaUploadService>();
+ private Dictionary<string, IMediaUploadService> pictureService = new();
private void CreateServices(Twitter tw, TwitterConfiguration twitterConfig)
{
public bool FilterModified { get; set; }
- private readonly List<PostFilterRule> filters = new List<PostFilterRule>();
- private readonly object lockObjFilters = new object();
+ private readonly List<PostFilterRule> filters = new();
+ private readonly object lockObjFilters = new();
public FilterTabModel(string tabName)
: base(tabName)
// 流速計測用
private int tweetsPerHour = 0;
- private readonly ConcurrentDictionary<DateTimeUtc, int> tweetsTimestamps = new ConcurrentDictionary<DateTimeUtc, int>();
+ private readonly ConcurrentDictionary<DateTimeUtc, int> tweetsTimestamps = new();
public HomeTabModel()
: this(MyCommon.DEFAULTTAB.RECENT)
{
public abstract class InternalStorageTabModel : TabModel
{
- protected readonly ConcurrentDictionary<long, PostClass> internalPosts = new ConcurrentDictionary<long, PostClass>();
+ protected readonly ConcurrentDictionary<long, PostClass> internalPosts = new();
public override ConcurrentDictionary<long, PostClass> Posts
=> this.internalPosts;
}
public ExpandedUrlInfo Clone()
- => new ExpandedUrlInfo(this.Url, this.ExpandedUrl, deepExpand: false);
+ => new(this.Url, this.ExpandedUrl, deepExpand: false);
object ICloneable.Clone()
=> this.Clone();
public IReadOnlyTabCollection Tabs
=> this.tabs;
- public MuteTabModel MuteTab { get; private set; } = new MuteTabModel();
+ public MuteTabModel MuteTab { get; private set; } = new();
- public ConcurrentDictionary<long, PostClass> Posts { get; } = new ConcurrentDictionary<long, PostClass>();
+ public ConcurrentDictionary<long, PostClass> Posts { get; } = new();
- private readonly Dictionary<long, PostClass> quotes = new Dictionary<long, PostClass>();
- private readonly ConcurrentDictionary<long, int> retweetsCount = new ConcurrentDictionary<long, int>();
+ private readonly Dictionary<long, PostClass> quotes = new();
+ private readonly ConcurrentDictionary<long, int> retweetsCount = new();
- public Stack<TabModel> RemovedTab { get; } = new Stack<TabModel>();
+ public Stack<TabModel> RemovedTab { get; } = new();
public ISet<long> BlockIds { get; set; } = new HashSet<long>();
// 発言の追加
// AddPost(複数回) -> DistributePosts -> SubmitUpdate
- private readonly TabCollection tabs = new TabCollection();
- private readonly ConcurrentQueue<long> addQueue = new ConcurrentQueue<long>();
+ private readonly TabCollection tabs = new();
+ private readonly ConcurrentQueue<long> addQueue = new();
/// <summary>通知サウンドを再生する優先順位</summary>
- private readonly Dictionary<MyCommon.TabUsageType, int> notifyPriorityByTabType = new Dictionary<MyCommon.TabUsageType, int>
+ private readonly Dictionary<MyCommon.TabUsageType, int> notifyPriorityByTabType = new()
{
[MyCommon.TabUsageType.DirectMessage] = 100,
[MyCommon.TabUsageType.Mentions] = 90,
};
// トランザクション用
- private readonly object lockObj = new object();
+ private readonly object lockObj = new();
- private static readonly TabInformations Instance = new TabInformations();
+ private static readonly TabInformations Instance = new();
// List
- private List<ListElement> lists = new List<ListElement>();
+ private List<ListElement> lists = new();
private TabInformations()
{
}
}
- private IndexedSortedSet<long> ids = new IndexedSortedSet<long>();
- private ConcurrentQueue<TemporaryId> addQueue = new ConcurrentQueue<TemporaryId>();
- private readonly ConcurrentQueue<long> removeQueue = new ConcurrentQueue<long>();
- private SortedSet<long> unreadIds = new SortedSet<long>();
- private List<long> selectedStatusIds = new List<long>();
+ private IndexedSortedSet<long> ids = new();
+ private ConcurrentQueue<TemporaryId> addQueue = new();
+ private readonly ConcurrentQueue<long> removeQueue = new();
+ private SortedSet<long> unreadIds = new();
+ private List<long> selectedStatusIds = new();
- private readonly object lockObj = new object();
+ private readonly object lockObj = new();
protected TabModel(string tabName)
=> this.TabName = tabName;
/// </summary>
public class MouseWheelMessageFilter : IMessageFilter
{
- private readonly List<Control> controls = new List<Control>();
+ private readonly List<Control> controls = new();
public MouseWheelMessageFilter()
=> Application.AddMessageFilter(this);
{
public static class MyCommon
{
- private static readonly object LockObj = new object();
+ private static readonly object LockObj = new();
public static bool EndingFlag { get; set; } // 終了フラグ
SearchResults = 4096,
}
- public static TwitterApiStatus TwitterApiInfo = new TwitterApiStatus();
+ public static TwitterApiStatus TwitterApiInfo = new();
public static bool IsAnimatedGif(string filename)
{
// .NET 4.5+: Reserved characters のうち、Uriクラスによってエスケープ強制解除されてしまうものも最初から Unreserved として扱う
private static readonly HashSet<char> UnreservedChars =
- new HashSet<char>("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!'()*:");
+ new("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~!'()*:");
/// <summary>
/// 2バイト文字も考慮したクエリ用エンコード
}
public WriteLockTransaction UpgradeToWriteLock()
- => new WriteLockTransaction(this.lockObj);
+ => new(this.lockObj);
public void Dispose()
=> this.lockObj.ExitUpgradeableReadLock();
[XmlAnyElement]
public XmlElement[] ExtraElements = Array.Empty<XmlElement>();
- private static readonly object LockObj = new object();
+ private static readonly object LockObj = new();
protected static T LoadSettings(string fileId)
{
=> SaveSettings(this);
#endregion
- public List<UserAccount> UserAccounts = new List<UserAccount>();
+ public List<UserAccount> UserAccounts = new();
public string UserName = "";
[XmlIgnore]
}
public long UserId = 0;
- public List<string> TabList = new List<string>();
+ public List<string> TabList = new();
public int TimelinePeriod = 90;
public int ReplyPeriod = 180;
public int DMPeriod = 600;
public bool ReadOldPosts = false;
public string Language = "OS";
public bool Nicoms = false;
- public List<string> HashTags = new List<string>();
+ public List<string> HashTags = new();
public string HashSelected = "";
public bool HashIsPermanent = false;
public bool HashIsHead = false;
/// </summary>
public SizeF ScaleDimension = SizeF.Empty;
- public Point FormLocation = new Point(0, 0);
+ public Point FormLocation = new(0, 0);
public int SplitterDistance = 200;
- public Size FormSize = new Size(600, 500);
+ public Size FormSize = new(600, 500);
/// <summary>
/// 文末ステータス
public int PreviewDistance = -1;
[XmlIgnore]
- public Font FontUnread = new Font(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline);
+ public Font FontUnread = new(SystemFonts.DefaultFont, FontStyle.Bold | FontStyle.Underline);
public string FontUnreadStr
{
public bool UseTwemoji = true;
[XmlIgnore]
- private readonly FontConverter fontConverter = new FontConverter();
+ private readonly FontConverter fontConverter = new();
protected string FontToString(Font font)
=> this.fontConverter.ConvertToString(font);
=> (Font)this.fontConverter.ConvertFromString(str);
[XmlIgnore]
- private readonly ColorConverter colorConverter = new ColorConverter();
+ private readonly ColorConverter colorConverter = new();
protected string ColorToString(Color color)
=> this.colorConverter.ConvertToString(color);
/// 指定されたスケールと SettingLocal.ScaleDimension のスケールとの拡大比を返します
/// </summary>
public SizeF GetConfigScaleFactor(SizeF currentSizeDimension)
- => new SizeF(
+ => new(
currentSizeDimension.Width / this.ScaleDimension.Width,
currentSizeDimension.Height / this.ScaleDimension.Height);
{
public static class SettingManager
{
- public static SettingCommon Common { get; internal set; } = new SettingCommon();
+ public static SettingCommon Common { get; internal set; } = new();
- public static SettingLocal Local { get; internal set; } = new SettingLocal();
+ public static SettingLocal Local { get; internal set; } = new();
- public static SettingTabs Tabs { get; internal set; } = new SettingTabs();
+ public static SettingTabs Tabs { get; internal set; } = new();
- public static SettingAtIdList AtIdList { get; internal set; } = new SettingAtIdList();
+ public static SettingAtIdList AtIdList { get; internal set; } = new();
public static void LoadAll()
{
public string BitlyKey { get; set; } = "";
private HttpClient http;
- private readonly ConcurrentDictionary<Uri, Uri> urlCache = new ConcurrentDictionary<Uri, Uri>();
+ private readonly ConcurrentDictionary<Uri, Uri> urlCache = new();
- private static readonly Regex HtmlLinkPattern = new Regex(@"(<a href="")(.+?)("")");
+ private static readonly Regex HtmlLinkPattern = new(@"(<a href="")(.+?)("")");
- private static readonly HashSet<string> ShortUrlHosts = new HashSet<string>
+ private static readonly HashSet<string> ShortUrlHosts = new()
{
"4sq.com",
"amzn.to",
/// <summary>
/// HTTPS非対応の短縮URLサービス
/// </summary>
- private static readonly HashSet<string> InsecureDomains = new HashSet<string>
+ private static readonly HashSet<string> InsecureDomains = new()
{
"budurl.com",
"ff.im",
{
private readonly ITimer throttlingTimer;
private readonly Func<Task> timerCallback;
- private readonly object lockObject = new object();
+ private readonly object lockObject = new();
private bool calledSinceLastInvoke;
private bool refreshTimerEnabled;
=> this.throttlingTimer.Dispose();
public static ThrottleTimer Create(Func<Task> callback, TimeSpan wait)
- => new ThrottleTimer(callback, wait);
+ => new(callback, wait);
}
}
public static readonly string TileServerBase = "https://a.tile.openstreetmap.org";
/// <summary>タイル画像一枚当たりの大きさ (ピクセル単位)</summary>
- public static readonly Size TileSize = new Size(256, 256);
+ public static readonly Size TileSize = new(256, 256);
/// <summary>画像の中心点の緯度</summary>
public double Latitude { get; }
public class FoursquareCheckin : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"^https?://www\.swarmapp\.com/c/(?<checkin_id>[0-9a-zA-Z]+)");
+ new(@"^https?://www\.swarmapp\.com/c/(?<checkin_id>[0-9a-zA-Z]+)");
public static readonly Regex LegacyUrlPatternRegex =
- new Regex(@"^https?://(?:foursquare\.com|www\.swarmapp\.com)/.+?/checkin/(?<checkin_id>[0-9a-z]+)(?:\?s=(?<signature>[^&]+))?");
+ new(@"^https?://(?:foursquare\.com|www\.swarmapp\.com)/.+?/checkin/(?<checkin_id>[0-9a-z]+)(?:\?s=(?<signature>[^&]+))?");
public static readonly string ApiBase = "https://api.foursquare.com/v2";
private readonly HttpClient? localHttpClient;
- private readonly object lockObj = new object();
+ private readonly object lockObj = new();
public ImgAzyobuziNet(bool autoupdate)
: this(null, autoupdate)
public class Nicovideo : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?<id>(?:sm|nm)?[0-9]+)(\?.+)?$");
+ new(@"^https?://(?:(www|ext)\.nicovideo\.jp/watch|nico\.ms)/(?<id>(?:sm|nm)?[0-9]+)(\?.+)?$");
public override async Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
public class PbsTwimgCom : IThumbnailService
{
public static readonly Regex ModernUrlPattern =
- new Regex(@"^(?<base_url>https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?<format>[A-Za-z]+)");
+ new(@"^(?<base_url>https?://pbs\.twimg\.com/[^:.]+)\?([^&]+?&)?format=(?<format>[A-Za-z]+)");
public static readonly Regex LegacyUrlPattern =
- new Regex(@"^(?<base_url>https?://pbs\.twimg\.com/[^.]+)\.(?<format>[A-Za-z]+)(?:\:.+)?$");
+ new(@"^(?<base_url>https?://pbs\.twimg\.com/[^.]+)\.(?<format>[A-Za-z]+)(?:\:.+)?$");
public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
=> Task.FromResult(this.GetThumbnailInfo(url, post, token));
public class Tinami : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"^https?://www\.tinami\.com/view/(?<ContentId>\d+)$");
+ new(@"^https?://www\.tinami\.com/view/(?<ContentId>\d+)$");
protected HttpClient Http
=> this.localHttpClient ?? Networking.Http;
public class Tumblr : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"^https?://(?<host>[^.]+\.tumblr\.com|tumblr\.[^.]+\.[^.]+)/post/(?<postId>[0-9]+)(/.*)?");
+ new(@"^https?://(?<host>[^.]+\.tumblr\.com|tumblr\.[^.]+\.[^.]+)/post/(?<postId>[0-9]+)(/.*)?");
protected HttpClient Http
=> this.localHttpClient ?? Networking.Http;
public class Vimeo : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"https?://vimeo\.com/(?<postID>[0-9]+)");
+ new(@"https?://vimeo\.com/(?<postID>[0-9]+)");
protected HttpClient Http
=> this.localHttpClient ?? Networking.Http;
public class Youtube : IThumbnailService
{
public static readonly Regex UrlPatternRegex =
- new Regex(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?<videoId>[\w\-]+)");
+ new(@"^https?://(?:(?:(?:m|www|music|gaming)\.)?youtube\.com/(?:watch\?(?:[^#]*&)?v=|embed/|shorts/)|youtu\.be/)(?<videoId>[\w\-]+)");
public override Task<ThumbnailInfo?> GetThumbnailInfoAsync(string url, PostClass post, CancellationToken token)
{
{
public class ThumbnailGenerator
{
- public static readonly Regex InstagramPattern = new Regex(
+ public static readonly Regex InstagramPattern = new(
@"^https?://(?:instagram.com|instagr\.am|i\.instagram\.com|www\.instagram\.com)/([^/]+/)?p/(?<mediaId>[^/]+)/(\?.*)?$",
RegexOptions.IgnoreCase
);
/// <summary>右クリックしたタブの名前(Tabコントロール機能不足対応)</summary>
private string? rclickTabName;
- private readonly object syncObject = new object(); // ロック用
+ private readonly object syncObject = new(); // ロック用
private const string DetailHtmlFormatHead =
"<head><meta http-equiv=\"X-UA-Compatible\" content=\"IE=8\">"
private FormWindowState formWindowState = FormWindowState.Normal; // フォームの状態保存用 通知領域からアイコンをクリックして復帰した際に使用する
// twitter解析部
- private readonly TwitterApi twitterApi = new TwitterApi(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret);
+ private readonly TwitterApi twitterApi = new(ApplicationSettings.TwitterConsumerKey, ApplicationSettings.TwitterConsumerSecret);
private Twitter tw = null!;
// Growl呼び出し部
- private readonly GrowlHelper gh = new GrowlHelper(ApplicationSettings.ApplicationName);
+ private readonly GrowlHelper gh = new(ApplicationSettings.ApplicationName);
// サブ画面インスタンス
/// <summary>検索画面インスタンス</summary>
- internal SearchWordDialog SearchDialog = new SearchWordDialog();
+ internal SearchWordDialog SearchDialog = new();
- private readonly OpenURL urlDialog = new OpenURL();
+ private readonly OpenURL urlDialog = new();
/// <summary>@id補助</summary>
public AtIdSupplement AtIdSupl = null!;
private Icon replyIcon = null!;
private Icon replyIconBlink = null!;
- private readonly ImageList listViewImageList = new ImageList(); // ListViewItemの高さ変更用
+ private readonly ImageList listViewImageList = new(); // ListViewItemの高さ変更用
private PostClass? anchorPost;
private bool anchorFlag; // true:関連発言移動中(関連移動以外のオペレーションをするとfalseへ。trueだとリスト背景色をアンカー発言選択中として描画)
/// <summary>発言履歴</summary>
- private readonly List<StatusTextHistory> history = new List<StatusTextHistory>();
+ private readonly List<StatusTextHistory> history = new();
/// <summary>発言履歴カレントインデックス</summary>
private int hisIdx;
private (long StatusId, string ScreenName)? inReplyTo = null;
// 時速表示用
- private readonly List<DateTimeUtc> postTimestamps = new List<DateTimeUtc>();
- private readonly List<DateTimeUtc> favTimestamps = new List<DateTimeUtc>();
+ private readonly List<DateTimeUtc> postTimestamps = new();
+ private readonly List<DateTimeUtc> favTimestamps = new();
// 以下DrawItem関連
- private readonly SolidBrush brsHighLight = new SolidBrush(Color.FromKnownColor(KnownColor.Highlight));
+ private readonly SolidBrush brsHighLight = new(Color.FromKnownColor(KnownColor.Highlight));
private SolidBrush brsBackColorMine = null!;
private SolidBrush brsBackColorAt = null!;
private SolidBrush brsBackColorYou = null!;
private SolidBrush brsBackColorNone = null!;
/// <summary>Listにフォーカスないときの選択行の背景色</summary>
- private readonly SolidBrush brsDeactiveSelection = new SolidBrush(Color.FromKnownColor(KnownColor.ButtonFace));
+ private readonly SolidBrush brsDeactiveSelection = new(Color.FromKnownColor(KnownColor.ButtonFace));
- private readonly StringFormat sfTab = new StringFormat();
+ private readonly StringFormat sfTab = new();
//////////////////////////////////////////////////////////////////////////////////////////////////////////
private TabInformations statuses = null!;
private bool isColumnChanged = false;
private const int MaxWorderThreads = 20;
- private readonly SemaphoreSlim workerSemaphore = new SemaphoreSlim(MaxWorderThreads);
- private readonly CancellationTokenSource workerCts = new CancellationTokenSource();
+ private readonly SemaphoreSlim workerSemaphore = new(MaxWorderThreads);
+ private readonly CancellationTokenSource workerCts = new();
private readonly IProgress<string> workerProgress = null!;
private int unreadCounter = -1;
//////////////////////////////////////////////////////////////////////////////////////////////////////////
- private readonly TimelineScheduler timelineScheduler = new TimelineScheduler();
+ private readonly TimelineScheduler timelineScheduler = new();
private DebounceTimer selectionDebouncer = null!;
private DebounceTimer saveConfigDebouncer = null!;
private Stack<ReplyChain>? replyChains;
/// <summary>ポスト選択履歴</summary>
- private readonly Stack<(TabModel, PostClass?)> selectPostChains = new Stack<(TabModel, PostClass?)>();
+ private readonly Stack<(TabModel, PostClass?)> selectPostChains = new();
public TabModel CurrentTab
=> this.statuses.SelectedTab;
private void DispSelectedPost()
=> this.DispSelectedPost(false);
- private PostClass displayPost = new PostClass();
+ private PostClass displayPost = new();
/// <summary>
/// サムネイル表示に使用する CancellationToken の生成元
{
public static class TweetExtractor
{
- public static readonly Regex EmojiPattern = new Regex(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f");
+ public static readonly Regex EmojiPattern = new(@"(?:\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83d\udc68\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc68\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc68\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc68\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffc-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffd-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb\udffc\udffe\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffd\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc68\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83d\udc69\ud83c[\udffb-\udfff]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc68\ud83c[\udffb-\udffe]|\ud83d\udc69\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83d\udc69\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udffb\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffc-\udfff]|\ud83e\uddd1\ud83c\udffb\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffd-\udfff]|\ud83e\uddd1\ud83c\udffc\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb\udffc\udffe\udfff]|\ud83e\uddd1\ud83c\udffd\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffd\udfff]|\ud83e\uddd1\ud83c\udffe\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83e\uddd1\ud83c\udfff\u200d\u2764\ufe0f\u200d\ud83e\uddd1\ud83c[\udffb-\udffe]|\ud83e\uddd1\ud83c\udfff\u200d\ud83e\udd1d\u200d\ud83e\uddd1\ud83c[\udffb-\udfff]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d\udc8b\u200d\ud83d[\udc68\udc69]|\ud83d\udc68\u200d\u2764\ufe0f\u200d\ud83d\udc68|\ud83d\udc69\u200d\u2764\ufe0f\u200d\ud83d[\udc68\udc69]|\ud83e\uddd1\u200d\ud83e\udd1d\u200d\ud83e\uddd1|\ud83d\udc6b\ud83c[\udffb-\udfff]|\ud83d\udc6c\ud83c[\udffb-\udfff]|\ud83d\udc6d\ud83c[\udffb-\udfff]|\ud83d\udc8f\ud83c[\udffb-\udfff]|\ud83d\udc91\ud83c[\udffb-\udfff]|\ud83d[\udc6b-\udc6d\udc8f\udc91])|(?:\ud83d[\udc68\udc69]|\ud83e\uddd1)(?:\ud83c[\udffb-\udfff])?\u200d(?:\u2695\ufe0f|\u2696\ufe0f|\u2708\ufe0f|\ud83c[\udf3e\udf73\udf7c\udf84\udf93\udfa4\udfa8\udfeb\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92]|\ud83e[\uddaf-\uddb3\uddbc\uddbd])|(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75]|\u26f9)((?:\ud83c[\udffb-\udfff]|\ufe0f)\u200d[\u2640\u2642]\ufe0f)|(?:\ud83c[\udfc3\udfc4\udfca]|\ud83d[\udc6e\udc70\udc71\udc73\udc77\udc81\udc82\udc86\udc87\ude45-\ude47\ude4b\ude4d\ude4e\udea3\udeb4-\udeb6]|\ud83e[\udd26\udd35\udd37-\udd39\udd3d\udd3e\uddb8\uddb9\uddcd-\uddcf\uddd4\uddd6-\udddd])(?:\ud83c[\udffb-\udfff])?\u200d[\u2640\u2642]\ufe0f|(?:\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc68\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc68\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc66\u200d\ud83d\udc66|\ud83d\udc69\u200d\ud83d\udc67\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f|\ud83c\udff3\ufe0f\u200d\ud83c\udf08|\ud83d\ude36\u200d\ud83c\udf2b\ufe0f|\u2764\ufe0f\u200d\ud83d\udd25|\u2764\ufe0f\u200d\ud83e\ude79|\ud83c\udff4\u200d\u2620\ufe0f|\ud83d\udc15\u200d\ud83e\uddba|\ud83d\udc3b\u200d\u2744\ufe0f|\ud83d\udc41\u200d\ud83d\udde8|\ud83d\udc68\u200d\ud83d[\udc66\udc67]|\ud83d\udc69\u200d\ud83d[\udc66\udc67]|\ud83d\udc6f\u200d\u2640\ufe0f|\ud83d\udc6f\u200d\u2642\ufe0f|\ud83d\ude2e\u200d\ud83d\udca8|\ud83d\ude35\u200d\ud83d\udcab|\ud83e\udd3c\u200d\u2640\ufe0f|\ud83e\udd3c\u200d\u2642\ufe0f|\ud83e\uddde\u200d\u2640\ufe0f|\ud83e\uddde\u200d\u2642\ufe0f|\ud83e\udddf\u200d\u2640\ufe0f|\ud83e\udddf\u200d\u2642\ufe0f|\ud83d\udc08\u200d\u2b1b)|[#*0-9]\ufe0f?\u20e3|(?:[©®\u2122\u265f]\ufe0f)|(?:\ud83c[\udc04\udd70\udd71\udd7e\udd7f\ude02\ude1a\ude2f\ude37\udf21\udf24-\udf2c\udf36\udf7d\udf96\udf97\udf99-\udf9b\udf9e\udf9f\udfcd\udfce\udfd4-\udfdf\udff3\udff5\udff7]|\ud83d[\udc3f\udc41\udcfd\udd49\udd4a\udd6f\udd70\udd73\udd76-\udd79\udd87\udd8a-\udd8d\udda5\udda8\uddb1\uddb2\uddbc\uddc2-\uddc4\uddd1-\uddd3\udddc-\uddde\udde1\udde3\udde8\uddef\uddf3\uddfa\udecb\udecd-\udecf\udee0-\udee5\udee9\udef0\udef3]|[\u203c\u2049\u2139\u2194-\u2199\u21a9\u21aa\u231a\u231b\u2328\u23cf\u23ed-\u23ef\u23f1\u23f2\u23f8-\u23fa\u24c2\u25aa\u25ab\u25b6\u25c0\u25fb-\u25fe\u2600-\u2604\u260e\u2611\u2614\u2615\u2618\u2620\u2622\u2623\u2626\u262a\u262e\u262f\u2638-\u263a\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267b\u267f\u2692-\u2697\u2699\u269b\u269c\u26a0\u26a1\u26a7\u26aa\u26ab\u26b0\u26b1\u26bd\u26be\u26c4\u26c5\u26c8\u26cf\u26d1\u26d3\u26d4\u26e9\u26ea\u26f0-\u26f5\u26f8\u26fa\u26fd\u2702\u2708\u2709\u270f\u2712\u2714\u2716\u271d\u2721\u2733\u2734\u2744\u2747\u2757\u2763\u2764\u27a1\u2934\u2935\u2b05-\u2b07\u2b1b\u2b1c\u2b50\u2b55\u3030\u303d\u3297\u3299])(?:\ufe0f|(?!\ufe0e))|(?:(?:\ud83c[\udfcb\udfcc]|\ud83d[\udd74\udd75\udd90]|[\u261d\u26f7\u26f9\u270c\u270d])(?:\ufe0f|(?!\ufe0e))|(?:\ud83c[\udf85\udfc2-\udfc4\udfc7\udfca]|\ud83d[\udc42\udc43\udc46-\udc50\udc66-\udc69\udc6e\udc70-\udc78\udc7c\udc81-\udc83\udc85-\udc87\udcaa\udd7a\udd95\udd96\ude45-\ude47\ude4b-\ude4f\udea3\udeb4-\udeb6\udec0\udecc]|\ud83e[\udd0c\udd0f\udd18-\udd1c\udd1e\udd1f\udd26\udd30-\udd39\udd3d\udd3e\udd77\uddb5\uddb6\uddb8\uddb9\uddbb\uddcd-\uddcf\uddd1-\udddd]|[\u270a\u270b]))(?:\ud83c[\udffb-\udfff])?|(?:\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc73\udb40\udc63\udb40\udc74\udb40\udc7f|\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc77\udb40\udc6c\udb40\udc73\udb40\udc7f|\ud83c\udde6\ud83c[\udde8-\uddec\uddee\uddf1\uddf2\uddf4\uddf6-\uddfa\uddfc\uddfd\uddff]|\ud83c\udde7\ud83c[\udde6\udde7\udde9-\uddef\uddf1-\uddf4\uddf6-\uddf9\uddfb\uddfc\uddfe\uddff]|\ud83c\udde8\ud83c[\udde6\udde8\udde9\uddeb-\uddee\uddf0-\uddf5\uddf7\uddfa-\uddff]|\ud83c\udde9\ud83c[\uddea\uddec\uddef\uddf0\uddf2\uddf4\uddff]|\ud83c\uddea\ud83c[\udde6\udde8\uddea\uddec\udded\uddf7-\uddfa]|\ud83c\uddeb\ud83c[\uddee-\uddf0\uddf2\uddf4\uddf7]|\ud83c\uddec\ud83c[\udde6\udde7\udde9-\uddee\uddf1-\uddf3\uddf5-\uddfa\uddfc\uddfe]|\ud83c\udded\ud83c[\uddf0\uddf2\uddf3\uddf7\uddf9\uddfa]|\ud83c\uddee\ud83c[\udde8-\uddea\uddf1-\uddf4\uddf6-\uddf9]|\ud83c\uddef\ud83c[\uddea\uddf2\uddf4\uddf5]|\ud83c\uddf0\ud83c[\uddea\uddec-\uddee\uddf2\uddf3\uddf5\uddf7\uddfc\uddfe\uddff]|\ud83c\uddf1\ud83c[\udde6-\udde8\uddee\uddf0\uddf7-\uddfb\uddfe]|\ud83c\uddf2\ud83c[\udde6\udde8-\udded\uddf0-\uddff]|\ud83c\uddf3\ud83c[\udde6\udde8\uddea-\uddec\uddee\uddf1\uddf4\uddf5\uddf7\uddfa\uddff]|\ud83c\uddf4\ud83c\uddf2|\ud83c\uddf5\ud83c[\udde6\uddea-\udded\uddf0-\uddf3\uddf7-\uddf9\uddfc\uddfe]|\ud83c\uddf6\ud83c\udde6|\ud83c\uddf7\ud83c[\uddea\uddf4\uddf8\uddfa\uddfc]|\ud83c\uddf8\ud83c[\udde6-\uddea\uddec-\uddf4\uddf7-\uddf9\uddfb\uddfd-\uddff]|\ud83c\uddf9\ud83c[\udde6\udde8\udde9\uddeb-\udded\uddef-\uddf4\uddf7\uddf9\uddfb\uddfc\uddff]|\ud83c\uddfa\ud83c[\udde6\uddec\uddf2\uddf3\uddf8\uddfe\uddff]|\ud83c\uddfb\ud83c[\udde6\udde8\uddea\uddec\uddee\uddf3\uddfa]|\ud83c\uddfc\ud83c[\uddeb\uddf8]|\ud83c\uddfd\ud83c\uddf0|\ud83c\uddfe\ud83c[\uddea\uddf9]|\ud83c\uddff\ud83c[\udde6\uddf2\uddfc]|\ud83c[\udccf\udd8e\udd91-\udd9a\udde6-\uddff\ude01\ude32-\ude36\ude38-\ude3a\ude50\ude51\udf00-\udf20\udf2d-\udf35\udf37-\udf7c\udf7e-\udf84\udf86-\udf93\udfa0-\udfc1\udfc5\udfc6\udfc8\udfc9\udfcf-\udfd3\udfe0-\udff0\udff4\udff8-\udfff]|\ud83d[\udc00-\udc3e\udc40\udc44\udc45\udc51-\udc65\udc6a\udc6f\udc79-\udc7b\udc7d-\udc80\udc84\udc88-\udc8e\udc90\udc92-\udca9\udcab-\udcfc\udcff-\udd3d\udd4b-\udd4e\udd50-\udd67\udda4\uddfb-\ude44\ude48-\ude4a\ude80-\udea2\udea4-\udeb3\udeb7-\udebf\udec1-\udec5\uded0-\uded2\uded5-\uded7\udeeb\udeec\udef4-\udefc\udfe0-\udfeb]|\ud83e[\udd0d\udd0e\udd10-\udd17\udd1d\udd20-\udd25\udd27-\udd2f\udd3a\udd3c\udd3f-\udd45\udd47-\udd76\udd78\udd7a-\uddb4\uddb7\uddba\uddbc-\uddcb\uddd0\uddde-\uddff\ude70-\ude74\ude78-\ude7a\ude80-\ude86\ude90-\udea8\udeb0-\udeb6\udec0-\udec2\uded0-\uded6]|[\u23e9-\u23ec\u23f0\u23f3\u267e\u26ce\u2705\u2728\u274c\u274e\u2753-\u2755\u2795-\u2797\u27b0\u27bf\ue50a])|\ufe0f");
/// <summary>
/// テキストから URL を抽出して返します
{
public partial class TweetThumbnail : UserControl
{
- protected internal List<OTPictureBox> PictureBox = new List<OTPictureBox>();
- protected MouseWheelMessageFilter filter = new MouseWheelMessageFilter();
+ protected internal List<OTPictureBox> PictureBox = new();
+ protected MouseWheelMessageFilter filter = new();
public event EventHandler<EventArgs>? ThumbnailLoading;
/// <summary>
/// ツイートへのパーマリンクURLを判定する正規表現
/// </summary>
- public static readonly Regex StatusUrlRegex = new Regex(@"https?://([^.]+\.)?twitter\.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)/status(es)?/(?<StatusId>[0-9]+)(/photo)?", RegexOptions.IgnoreCase);
+ public static readonly Regex StatusUrlRegex = new(@"https?://([^.]+\.)?twitter\.com/(#!/)?(?<ScreenName>[a-zA-Z0-9_]+)/status(es)?/(?<StatusId>[0-9]+)(/photo)?", RegexOptions.IgnoreCase);
/// <summary>
/// attachment_url に指定可能な URL を判定する正規表現
/// </summary>
- public static readonly Regex AttachmentUrlRegex = new Regex(
+ public static readonly Regex AttachmentUrlRegex = new(
@"https?://(
twitter\.com/[0-9A-Za-z_]+/status/[0-9]+
| mobile\.twitter\.com/[0-9A-Za-z_]+/status/[0-9]+
/// <summary>
/// FavstarやaclogなどTwitter関連サービスのパーマリンクURLからステータスIDを抽出する正規表現
/// </summary>
- public static readonly Regex ThirdPartyStatusUrlRegex = new Regex(
+ public static readonly Regex ThirdPartyStatusUrlRegex = new(
@"https?://(?:[^.]+\.)?(?:
favstar\.fm/users/[a-zA-Z0-9_]+/status/ # Favstar
| favstar\.fm/t/ # Favstar (short)
/// <summary>
/// DM送信かどうかを判定する正規表現
/// </summary>
- public static readonly Regex DMSendTextRegex = new Regex(@"^DM? +(?<id>[a-zA-Z0-9_]+) +(?<body>.*)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
+ public static readonly Regex DMSendTextRegex = new(@"^DM? +(?<id>[a-zA-Z0-9_]+) +(?<body>.*)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
public TwitterApi Api { get; }
private delegate void GetIconImageDelegate(PostClass post);
- private readonly object lockObj = new object();
+ private readonly object lockObj = new();
private ISet<long> followerId = new HashSet<long>();
private long[] noRTId = Array.Empty<long>();
// プロパティからアクセスされる共通情報
- private readonly List<string> hashList = new List<string>();
+ private readonly List<string> hashList = new();
private string? nextCursorDirectMessage = null;
return text;
}
- private static readonly Uri SourceUriBase = new Uri("https://twitter.com/");
+ private static readonly Uri SourceUriBase = new("https://twitter.com/");
/// <summary>
/// Twitter APIから得たHTML形式のsource文字列を分析し、source名とURLに分離します