/// <inheritdoc /> public override async ValueTask <Result <IRole> > TryParse(string value, CancellationToken ct) { if (!Snowflake.TryParse(value.Unmention(), out var roleID)) { return(new ParsingError <IRole>(value.Unmention())); } var getChannel = await _channelAPI.GetChannelAsync(_context.ChannelID, ct); if (!getChannel.IsSuccess) { return(Result <IRole> .FromError(new GenericError("Failed to get a valid channel."), getChannel)); } var channel = getChannel.Entity; if (!channel.GuildID.HasValue) { return(new GenericError("You're not in a guild channel, so I can't get any roles.")); } var getRoles = await _guildAPI.GetGuildRolesAsync(channel.GuildID.Value, ct); if (!getRoles.IsSuccess) { return(Result <IRole> .FromError(new GenericError("Failed to get the guild's roles."), getRoles)); } var roles = getRoles.Entity; var role = roles.FirstOrDefault(r => r.ID.Equals(roleID)); return(role is not null ? Result <IRole> .FromSuccess(role) : new GenericError("No role with that ID could be found.")); }
public async Task <Result> RespondAsync(IMessageReactionAdd ev, CancellationToken ct = default) { if (ev.ChannelID.Value != _discordSettings.FeedbackChannelId || !ev.GuildID.HasValue || !ev.Member.HasValue || ev.Member.Value.User.HasValue && ev.Member.Value.User.Value.IsBot.HasValue && ev.Member.Value.User.Value.IsBot.Value || !ev.Emoji.Name.HasValue || ev.Emoji.Name.Value is null || !_protectedEmojis.Contains(ev.Emoji.Name.Value) ) { return(Result.FromSuccess()); } var getChannelResult = await _channelApi.GetChannelAsync(ev.ChannelID, ct); if (!getChannelResult.IsSuccess) { return(Result.FromError(getChannelResult)); } var getGuildRolesResult = await _guildApi.GetGuildRolesAsync(ev.GuildID.Value, ct); if (!getGuildRolesResult.IsSuccess) { return(Result.FromError(getGuildRolesResult)); } var channel = getChannelResult.Entity; var guildRoles = getGuildRolesResult.Entity; var everyoneRole = guildRoles.FirstOrDefault(r => r.ID == ev.GuildID.Value); if (everyoneRole is null) { return(new NotFoundError("No @everyone role found.")); } var memberRoles = guildRoles.Where(r => ev.Member.Value.Roles.Contains(r.ID)).ToList(); var computedPermissions = channel.PermissionOverwrites.HasValue ? DiscordPermissionSet.ComputePermissions(ev.UserID, everyoneRole, memberRoles, channel.PermissionOverwrites.Value) : DiscordPermissionSet.ComputePermissions(ev.UserID, everyoneRole, memberRoles); return(computedPermissions.HasPermission(DiscordPermission.Administrator) || computedPermissions.HasPermission(DiscordPermission.BanMembers) ? Result.FromSuccess() : await _channelApi.DeleteUserReactionAsync(ev.ChannelID, ev.MessageID, ev.Emoji.Name.Value, ev.UserID, ct)); }
public async Task <Result <QueryResult> > Handle(Query request, CancellationToken cancellationToken) { var getGuildRolesResult = await _guildApi.GetGuildRolesAsync(request.GuildId, cancellationToken); if (!getGuildRolesResult.IsSuccess) { return(Result <QueryResult> .FromError(getGuildRolesResult)); } var getGuildChannelsResult = await _guildApi.GetGuildChannelsAsync(request.GuildId, cancellationToken); if (!getGuildChannelsResult.IsSuccess) { return(Result <QueryResult> .FromError(getGuildChannelsResult)); } var roles = getGuildRolesResult.Entity; if (roles is null) { return(new NotFoundError($"Could not find roles in guild {request.GuildId}.")); } var channels = getGuildChannelsResult.Entity; if (channels is null) { return(new NotFoundError($"Could not find channels in guild {request.GuildId}.")); } var staffRole = roles.FirstOrDefault(r => r.Name.Equals(_roleNames.Staff)); if (staffRole is null) { return(new NotFoundError( $"Could not find Staff role ({_roleNames.Staff}) in guild {request.GuildId}.")); } var membersChannel = channels.FirstOrDefault(c => c.Name.Equals(_channelNames.MemberApps)); if (membersChannel is null) { return(new NotFoundError( $"Could not find member apps channel (#{_channelNames.MemberApps}) in guild {request.GuildId}.")); } return(new QueryResult(membersChannel.ID, staffRole.ID)); }
/// <inheritdoc /> public override async ValueTask <Result <IRole> > TryParse(string value, CancellationToken ct) { var getChannel = await _channelAPI.GetChannelAsync(_context.ChannelID, ct); if (!getChannel.IsSuccess) { return(Result <IRole> .FromError(getChannel)); } var channel = getChannel.Entity; if (!channel.GuildID.HasValue) { return(new InvalidOperationError("You're not in a guild channel, so I can't get any roles.")); } var getRoles = await _guildAPI.GetGuildRolesAsync(channel.GuildID.Value, ct); if (!getRoles.IsSuccess) { return(Result <IRole> .FromError(getRoles)); } var roles = getRoles.Entity; if (!Snowflake.TryParse(value.Unmention(), out var roleID)) { // Try a name-based lookup var roleByName = roles.FirstOrDefault(r => r.Name.Equals(value, StringComparison.OrdinalIgnoreCase)); return(roleByName is not null ? Result <IRole> .FromSuccess(roleByName) : new ParsingError <IRole>(value.Unmention())); } var role = roles.FirstOrDefault(r => r.ID.Equals(roleID)); return(role is not null ? Result <IRole> .FromSuccess(role) : new ParsingError <IRole>("No role with that ID could be found.")); }
public async Task <Result <FeedbackMessage> > SetCharacterRoleAsync ( [RequireEntityOwner] [AutocompleteProvider("character::owned")] Character character, IRole discordRole ) { var getRoleResult = await _characterRoles.GetCharacterRoleAsync ( _context.GuildID.Value, discordRole.ID, this.CancellationToken ); if (!getRoleResult.IsSuccess) { return(Result <FeedbackMessage> .FromError(getRoleResult)); } // Get a bunch of stuff for permission checking... var getMember = await _guildAPI.GetGuildMemberAsync ( _context.GuildID.Value, _context.User.ID, this.CancellationToken ); if (!getMember.IsSuccess) { return(Result <FeedbackMessage> .FromError(getMember)); } var member = getMember.Entity; var getGuildRoles = await _guildAPI.GetGuildRolesAsync(_context.GuildID.Value, this.CancellationToken); if (!getGuildRoles.IsSuccess) { return(Result <FeedbackMessage> .FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var everyoneRole = guildRoles.First(r => r.ID == _context.GuildID.Value); var memberRoles = guildRoles.Where(r => member.Roles.Contains(r.ID)).ToList(); // We ignore channel overrides here; the user should have it on a guild level var computedPermissions = DiscordPermissionSet.ComputePermissions ( _context.User.ID, everyoneRole, memberRoles ); var characterRole = getRoleResult.Entity; if (characterRole.Access == RoleAccess.Restricted) { if (!computedPermissions.HasPermission(DiscordPermission.ManageRoles)) { return(new UserError ( "That role is restricted, and you must be able to manage roles to use it." )); } } var setRoleResult = await _characterRoles.SetCharacterRoleAsync ( _context.GuildID.Value, _context.User.ID, character, characterRole, this.CancellationToken ); return(!setRoleResult.IsSuccess ? Result <FeedbackMessage> .FromError(setRoleResult) : new FeedbackMessage("Character role set.", _feedback.Theme.Secondary)); }
/// <inheritdoc /> public async ValueTask <Result> CheckHasRequiredPermission( DiscordPermission permission, Snowflake channelId, IUser userToCheck, CancellationToken ct = default ) { var getChannel = await _channelApi.GetChannelAsync(channelId, ct); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var channel = getChannel.Entity; if (!channel.GuildID.HasValue) { return(new ConditionNotSatisfiedError( "Command requires a guild permission but was executed outside of a guild.")); } var guildId = channel.GuildID.Value; var getGuildMember = await _guildApi.GetGuildMemberAsync(guildId, userToCheck.ID, ct); if (!getGuildMember.IsSuccess) { return(Result.FromError(getGuildMember)); } var getGuildRoles = await _guildApi.GetGuildRolesAsync(guildId, ct); if (!getGuildRoles.IsSuccess) { return(Result.FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var everyoneRole = guildRoles.FirstOrDefault(r => r.Name.Equals("@everyone")); if (everyoneRole is null) { return(new NotFoundError("No @everyone role found.")); } var user = getGuildMember.Entity; if (user is null) { return(new NotFoundError("Executing user not found")); } var getGuild = await _guildApi.GetGuildAsync(guildId, ct : ct); if (!getGuild.IsSuccess) { return(Result.FromError(getGuild)); } var guildOwnerId = getGuild.Entity.OwnerID; // succeed if the user is the Owner of the guild if (guildOwnerId.Equals(userToCheck.ID)) { return(Result.FromSuccess()); } var memberRoles = guildRoles.Where(r => user.Roles.Contains(r.ID)).ToList(); var computedPermissions = channel.PermissionOverwrites switch { { HasValue : true, Value : { } overwrites } => DiscordPermissionSet.ComputePermissions(
/// <summary> /// Posts a notification that a message was deleted. /// </summary> /// <param name="message">The deleted message.</param> /// <param name="guildID">The ID of the guild in which the message was.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task <Result> NotifyMessageDeletedAsync(IMessage message, Snowflake guildID) { // We don't care about bot messages var isNonFeedbackMessage = (message.Author.IsBot.IsDefined(out var isBot) && isBot) || (message.Author.IsSystem.IsDefined(out var isSystem) && isSystem); if (isNonFeedbackMessage) { return(Result.FromSuccess()); } var getChannel = await GetMonitoringChannelAsync(guildID); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var getSelf = await _userAPI.GetCurrentUserAsync(); if (!getSelf.IsSuccess) { return(Result.FromError(getSelf)); } var self = getSelf.Entity; var channel = getChannel.Entity; var eb = new Embed { Colour = _feedback.Theme.Warning, Title = "Message Deleted" }; var getGuildRoles = await _guildAPI.GetGuildRolesAsync(guildID); if (!getGuildRoles.IsSuccess) { return(Result.FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var everyoneRole = guildRoles.First(r => r.ID == guildID); var getGuildMember = await _guildAPI.GetGuildMemberAsync(guildID, self.ID); if (!getGuildMember.IsSuccess) { return(Result.FromError(getGuildMember)); } var botGuildMember = getGuildMember.Entity; var botRoles = guildRoles.Where(r => botGuildMember.Roles.Contains(r.ID)).ToList(); var botPermissions = DiscordPermissionSet.ComputePermissions ( self.ID, everyoneRole, botRoles ); var extra = string.Empty; if (botPermissions.HasPermission(DiscordPermission.ViewAuditLog)) { var getMostProbableDeleter = await FindMostProbableDeleterAsync(message, guildID); if (!getMostProbableDeleter.IsSuccess) { return(Result.FromError(getMostProbableDeleter)); } var userID = getMostProbableDeleter.Entity; var getUser = await _userAPI.GetUserAsync(userID); if (!getUser.IsSuccess) { return(Result.FromError(getUser)); } var mostProbableDeleter = getUser.Entity; var isNonUserDeleter = (mostProbableDeleter.IsBot.IsDefined(out var isDeleterBot) && isDeleterBot) || (mostProbableDeleter.IsSystem.IsDefined(out var isDeleterSystem) && isDeleterSystem); // We don't care about bot deletions if (!isNonUserDeleter) { extra = $" (probably) by <@{mostProbableDeleter.ID}>"; } } eb = eb with { Description = $"A message was deleted from <#{message.ChannelID}>{extra}." }; var quote = QuoteService.CreateMessageQuote(message, self.ID); var sendResult = await _feedback.SendEmbedAsync(channel, eb); if (!sendResult.IsSuccess) { return(Result.FromError(sendResult)); } sendResult = await _feedback.SendEmbedAsync(channel, quote); return(sendResult.IsSuccess ? Result.FromSuccess() : Result.FromError(sendResult)); }
/// <inheritdoc /> public async ValueTask <Result> CheckHasRequiredPermission( DiscordPermission permission, Snowflake channelId, IUser userToCheck, CancellationToken ct = default ) { var getChannel = await _channelApi.GetChannelAsync(channelId, ct); if (!getChannel.IsSuccess) { return(Result.FromError(getChannel)); } var channel = getChannel.Entity; if (!channel.GuildID.HasValue) { return(new ConditionNotSatisfiedError( "Command requires a guild permission but was executed outside of a guild.")); } var guildId = channel.GuildID.Value; var getGuildMember = await _guildApi.GetGuildMemberAsync(guildId, userToCheck.ID, ct); if (!getGuildMember.IsSuccess) { return(Result.FromError(getGuildMember)); } var getGuildRoles = await _guildApi.GetGuildRolesAsync(guildId, ct); if (!getGuildRoles.IsSuccess) { return(Result.FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var everyoneRole = guildRoles.FirstOrDefault(r => r.Name.Equals("@everyone")); if (everyoneRole is null) { return(new NotFoundError("No @everyone role found.")); } var user = getGuildMember.Entity; if (user is null) { return(new NotFoundError("Executing user not found")); } var getGuild = await _guildApi.GetGuildAsync(guildId, ct : ct); if (!getGuild.IsSuccess) { return(Result.FromError(getGuild)); } var guildOwnerId = getGuild.Entity.OwnerID; // succeed if the user is the Owner of the guild if (guildOwnerId.Equals(userToCheck.ID)) { return(Result.FromSuccess()); } var memberRoles = guildRoles.Where(r => user.Roles.Contains(r.ID)).ToList(); IDiscordPermissionSet computedPermissions; if (channel.PermissionOverwrites.HasValue) { computedPermissions = DiscordPermissionSet.ComputePermissions( userToCheck.ID, everyoneRole, memberRoles, channel.PermissionOverwrites.Value ); } else { computedPermissions = DiscordPermissionSet.ComputePermissions( userToCheck.ID, everyoneRole, memberRoles ); } // succeed if the user is an Administrator of the guild if (computedPermissions.HasPermission(DiscordPermission.Administrator)) { return(Result.FromSuccess()); } var hasPermission = computedPermissions.HasPermission(permission); return(!hasPermission ? new ConditionNotSatisfiedError( $"Guild User requesting the command does not have the required {permission.ToString()} permission") : Result.FromSuccess()); }
/// <summary> /// Drones the given user, creating a randomized sharkdrone character for them and forcing them into that form. /// </summary> /// <param name="guildID">The ID of the guild the user is on.</param> /// <param name="userID">The ID of the user.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <Result <Character> > DroneUserAsync ( Snowflake guildID, Snowflake userID, CancellationToken ct = default ) { var createGeneratedIdentity = await GenerateDroneIdentityAsync(guildID, userID, ct); if (!createGeneratedIdentity.IsSuccess) { return(Result <Character> .FromError(createGeneratedIdentity)); } var(name, nickname) = createGeneratedIdentity.Entity; var generatedCharacterResult = await _characters.CreateCharacterAsync ( guildID, userID, name, _content.GetRandomDroneAvatarUri().ToString(), nickname, _content.GetRandomDroneSummary(), _content.GetRandomDroneDescription(), new FemininePronounProvider().Family, ct ); if (!generatedCharacterResult.IsSuccess) { return(generatedCharacterResult); } var character = generatedCharacterResult.Entity; var getGuildRoles = await _guildAPI.GetGuildRolesAsync(guildID, ct); if (!getGuildRoles.IsSuccess) { return(Result <Character> .FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var droneRole = guildRoles.FirstOrDefault ( r => r.Name.Contains("Drone") || r.Name.Contains("Dronies") ); if (droneRole is not null) { var getCharacterRole = await _characterRoles.GetCharacterRoleAsync(guildID, droneRole.ID, ct); if (getCharacterRole.IsSuccess) { var characterRole = getCharacterRole.Entity; var setCharacterRole = await _characterRoles.SetCharacterRoleAsync ( guildID, userID, character, characterRole, ct ); if (!setCharacterRole.IsSuccess) { return(Result <Character> .FromError(setCharacterRole)); } } } var becomeCharacterResult = await _characters.MakeCharacterCurrentAsync(guildID, userID, character, ct); return(!becomeCharacterResult.IsSuccess ? Result <Character> .FromError(becomeCharacterResult) : character); }
public async Task <Result> ListAvailableRolesAsync() { var baseEmbed = new Embed { Colour = _feedback.Theme.Secondary, Title = "Available character roles", Description = "These are the roles you can apply to your characters to automatically switch you " + "to that role when you assume the character.\n" + "\n" + "In order to avoid mentioning everyone that has the role, use the numerical ID or " + "role name instead of the actual mention. The ID is listed below along with the " + "role name." }; var getCharacterRoles = await _characterRoles.GetCharacterRolesAsync(_context.GuildID.Value); if (!getCharacterRoles.IsSuccess) { return(Result.FromError(getCharacterRoles)); } var characterRoles = getCharacterRoles.Entity; if (!characterRoles.Any()) { baseEmbed = baseEmbed with { Footer = new EmbedFooter("There aren't any character roles available in this server.") }; return((Result)await _feedback.SendContextualPaginatedMessageAsync ( _context.User.ID, new[] { baseEmbed }, ct : this.CancellationToken )); } var getGuildRoles = await _guildAPI.GetGuildRolesAsync(_context.GuildID.Value, this.CancellationToken); if (!getGuildRoles.IsSuccess) { return(Result.FromError(getGuildRoles)); } var guildRoles = getGuildRoles.Entity; var fields = characterRoles.Select ( r => { var guildRole = guildRoles.FirstOrDefault(gr => gr.ID == r.DiscordID); var roleStatus = r.Access == RoleAccess.Open ? "open to everyone" : "restricted"; var name = guildRole is null ? $"??? ({r.DiscordID} - this role appears to be deleted.)" : $"{guildRole.Name} ({r.DiscordID})"; var value = $"*This role is {roleStatus}.*"; return(new EmbedField(name, value)); } ); var pages = PageFactory.FromFields(fields, pageBase: baseEmbed); return((Result)await _feedback.SendContextualPaginatedMessageAsync ( _context.User.ID, pages, ct : this.CancellationToken )); }
/// <inheritdoc /> public async Task <Result <MemberApplication> > Handle(Command request, CancellationToken cancellationToken) { var app = await _context.MemberApplications .FirstOrDefaultAsync( a => a.MemberApplicationId == request.Id && a.GuildId == request.GuildId.Value, cancellationToken); if (app is null) { return(new NotFoundError($"Application with ID `{request.Id}` does not exist")); } var getRoles = await _guildApi.GetGuildRolesAsync(request.GuildId, cancellationToken); if (!getRoles.IsSuccess) { return(Result <MemberApplication> .FromError(getRoles.Error)); } var role = getRoles.Entity .FirstOrDefault(r => r.Name.Contains($"[{request.ServerPrefix.ToUpper()}]")); if (role is null) { return(new NotFoundError( $"Could not find a role corresponding to the server prefix: `{request.ServerPrefix}`.")); } var userId = new Snowflake(app.AuthorDiscordId); var getUserToPromoteResult = await _guildApi.GetGuildMemberAsync(request.GuildId, userId, cancellationToken); if (!getUserToPromoteResult.IsSuccess) { return(Result <MemberApplication> .FromError(getUserToPromoteResult.Error)); } if (getUserToPromoteResult.Entity is null) { return(new NotFoundError($"Could not find a user with ID: `{app.AuthorDiscordId}`.")); } foreach (var ign in request.Igns) { var proto = new GenericCommand { DiscordChannelId = request.ChannelId.ToString(), DiscordCommandName = "promote", DefaultCommand = "ranks add $1 member", Args = { ign } }; var id = request.ServerPrefix.ToUpperInvariant(); var server = _ps.GetOnlineServerOrDefault(id); if (server is null) { return(Result <MemberApplication> .FromError( new NotFoundError($"Could not find server with ID {id}"))); } await _ps.SendMessage(server, proto); } var addRoleResult = await _guildApi.AddGuildMemberRoleAsync(request.GuildId, userId, role.ID, new(), cancellationToken); if (!addRoleResult.IsSuccess) { return(Result <MemberApplication> .FromError(addRoleResult)); } app.AppStatus = ApplicationStatus.Approved; await _context.SaveChangesAsync(cancellationToken); return(Result <MemberApplication> .FromSuccess(app)); }
/// <summary> /// Applies the given autorole to the given user, if it is applicable. If the user no longer qualifies, /// the autorole is removed. /// </summary> /// <param name="autorole">The autorole.</param> /// <param name="guildID">The ID of the guild the user is on.</param> /// <param name="userID">The ID of the user.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <Result <AutoroleUpdateStatus> > UpdateAutoroleForUserAsync ( AutoroleConfiguration autorole, Snowflake guildID, Snowflake userID, CancellationToken ct = default ) { if (!autorole.IsEnabled) { return(Disabled); } if (!autorole.Conditions.Any()) { return(Unconditional); } var getRoles = await _guildAPI.GetGuildRolesAsync(guildID, ct); if (!getRoles.IsSuccess) { return(Result <AutoroleUpdateStatus> .FromError(getRoles)); } var roles = getRoles.Entity; if (roles.All(r => r.ID != autorole.DiscordRoleID)) { // If the role can't be found any longer, we disable it var disableAutoroleAsync = await _autoroles.DisableAutoroleAsync(autorole, ct); return(!disableAutoroleAsync.IsSuccess ? Result <AutoroleUpdateStatus> .FromError(disableAutoroleAsync) : Disabled); } var getIsUserQualified = await _autoroles.IsUserQualifiedForAutoroleAsync(autorole, userID, ct); if (!getIsUserQualified.IsSuccess) { return(Result <AutoroleUpdateStatus> .FromError(getIsUserQualified)); } var isUserQualified = getIsUserQualified.Entity; var getMember = await _guildAPI.GetGuildMemberAsync(guildID, userID, ct); if (!getMember.IsSuccess) { return(Result <AutoroleUpdateStatus> .FromError(getMember)); } var member = getMember.Entity; if (!member.User.IsDefined(out var user)) { return(Unqualified); } if (user.IsBot.IsDefined(out var isBot) && isBot) { return(Unqualified); } var userHasRole = member.Roles.Contains(autorole.DiscordRoleID); switch (isUserQualified) { case true when userHasRole: { return(Unchanged); } case false when userHasRole: { var removeRole = await _guildAPI.RemoveGuildMemberRoleAsync ( guildID, userID, autorole.DiscordRoleID, ct : ct ); if (!removeRole.IsSuccess) { return(Result <AutoroleUpdateStatus> .FromError(removeRole)); } var getConfirmation = await _autoroles.GetOrCreateAutoroleConfirmationAsync ( autorole, userID, ct ); if (!getConfirmation.IsSuccess) { return(Removed); } // Remove any existing affirmation var confirmation = getConfirmation.Entity; var removeConfirmation = await _autoroles.RemoveAutoroleConfirmationAsync(confirmation, ct); return(!removeConfirmation.IsSuccess ? Result <AutoroleUpdateStatus> .FromError(removeConfirmation) : Removed); } case false: { // At this point, the user doesn't have the role, and either is or is not qualified. // We consider a no-op for an unqualified user a success. return(Unqualified); } } if (autorole.RequiresConfirmation) { var getConfirmation = await _autoroles.GetOrCreateAutoroleConfirmationAsync ( autorole, userID, ct ); if (!getConfirmation.IsSuccess) { return(Result <AutoroleUpdateStatus> .FromError(getConfirmation)); } var confirmation = getConfirmation.Entity; if (!confirmation.IsConfirmed) { // We consider a no-op for an qualified but not affirmed user a success. return(RequiresAffirmation); } } var addRole = await _guildAPI.AddGuildMemberRoleAsync(guildID, userID, autorole.DiscordRoleID, ct : ct); return(!addRole.IsSuccess ? Result <AutoroleUpdateStatus> .FromError(addRole) : Applied); }