b0VIM 8.1�������p�_��V�K�josh������������������������������������Joshs-Mac-mini.local��������������������~josh/Projects/fastlane/fastlane/deliver/lib/deliver/upload_metadata.rb������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������utf-8 �3210����#"! U�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������tp�����������a����������������������������T�������b���������������������\�����������������������������T���������������������������g�������j��������������������c����������������������������?�������4�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������ad�����������a����������������������r��;����������������u��K��E��D����� ��� ��� ��� ��� ��z ��f ��J ��# ��������������z�������������v��P��,����� ��� ��� ��s ��m ��K ��% �� ��� ��� ��� ��h ��S ��M ��L �� ��������E���������o��n��:������������u��t��V��U�������������������P��O������������H�����������p��+��������������?���������������� # we don't want to update the localised_options and non_localised_options� version = app.get_edit_app_store_version(platform: platform)� UI.message("Couldn't find live version, editing the current version on App Store Connect instead")� if v.nil?�� non_localised_options = NON_LOCALISED_LIVE_VALUES� localised_options = LOCALISED_LIVE_VALUES� version = app.get_live_app_store_version(platform: platform)� # not all values are editable when using live_version� if options[:edit_live]�� app_info_localizations = verify_available_info_languages!(options, app, enabled_languages) unless options[:edit_live]� app_store_version_localizations = verify_available_version_languages!(options, app, enabled_languages) unless options[:edit_live]�� enabled_languages = detect_languages(options)�� platform = Spaceship::ConnectAPI::Platform.map(options[:platform])�� app = Spaceship::ConnectAPI::App.get(app_id: app_id)� app_id = legacy_app.apple_id� legacy_app = options[:app]�� return if options[:skip_metadata]� def upload(options)� # Make sure to call `load_from_filesystem` before calling upload�� require_relative 'loader'�� # rubocop:disable Metrics/PerceivedComplexity�� ALL_META_SUB_DIRS = [TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR, REVIEW_INFORMATION_DIR]�� REVIEW_INFORMATION_DIR = "review_information"� # Directory name it contains review information�� TRADE_REPRESENTATIVE_CONTACT_INFORMATION_DIR = "trade_representative_contact_information"� # Directory name it contains trade representative contact information�� NON_LOCALISED_LIVE_VALUES = [:copyright]� # Non localized app details values, that are editable in live state�� LOCALISED_LIVE_VALUES = [:description, :release_notes, :support_url, :marketing_url, :promotional_text, :privacy_url]� # Localized app details values, that are editable in live state�� }� notes: "notes"� demo_password: "demoAccountPassword",� demo_user: "demoAccountName",� email_address: "contactEmail",� phone_number: "contactPhone",� last_name: "contactLastName",� first_name: "contactFirstName",� REVIEW_INFORMATION_VALUES = {� }� review_notes: :notes� review_demo_password: :demo_password,� review_demo_user: :demo_user,� review_email: :email_address,� review_phone_number: :phone_number,� review_last_name: :last_name,� review_first_name: :first_name,� REVIEW_INFORMATION_VALUES_LEGACY = {� # Review information values�� :secondary_first_sub_category, :secondary_second_sub_category]� :primary_first_sub_category, :primary_second_sub_category,� NON_LOCALISED_APP_VALUES = [:primary_category, :secondary_category,� # Non localized app details values�� }� apple_tv_privacy_policy: "privacyPolicyText"� privacy_url: "privacyPolicyUrl",� subtitle: "subtitle",� name: "name",� LOCALISED_APP_VALUES = {� # Localised app details values�� }� copyright: "copyright"� NON_LOCALISED_VERSION_VALUES = {� # Everything attached to the version but not being localised�� }� promotional_text: "promotionalText"� marketing_url: "marketingUrl",� support_url: "supportUrl",� release_notes: "whatsNew",� keywords: "keywords",� description: "description",� LOCALISED_VERSION_VALUES = {� # All the localised values attached to the version� class UploadMetadata� # rubocop:disable Metrics/ClassLength� # upload description, rating, etc.�module Deliver��require_relative 'module'�ad��c��{�����?�������������������q��+�����������Q��� ��� ��� ��� ��r �� �� �����^��T��L��K��"�����������������q��W��� ��� ��� ��� ��v ��] ��G ��- ��� ��| ��{ ��X ��3 ��2 �� ��� ��������������a��J��)��������5��4����������������{��z�������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������end� # rubocop:enable Metrics/ClassLength� end� end� age_rating_delcaration.update(attributes: attributes)� age_rating_delcaration = version.fetch_age_rating_declaration�� UI.deprecated("You can find more info at https://docs.fastlane.tools/actions/deliver/#reference") if has_mapped_values� end� UI.deprecated("Age rating '#{k}' from iTunesConnect as been deprecated. Please replace with '#{v}'")� has_mapped_values = true� next if k == v� next if k.nil? || v.nil?� mapped_values.each do |k, v|� has_mapped_values = false� # Print deprecation warnings if category was mapped�� end� attributes[new_key] = new_value�� mapped_values[v] = new_value� mapped_values[k] = new_key�� new_value = Spaceship::ConnectAPI::AgeRatingDeclaration.map_value_from_itc(new_key, v)� new_key = Spaceship::ConnectAPI::AgeRatingDeclaration.map_key_from_itc(k)� json.each do |k, v|� attributes = {}� mapped_values = {}� # Maping from legacy ITC values to App Store Connect Values�� UI.message("Setting the app's age rating...")� end� UI.user_error!("Error parsing JSON file at path '#{options[:app_rating_config_path]}'")� UI.error(ex.to_s)� rescue => ex� json = JSON.parse(File.read(options[:app_rating_config_path]))� begin� require 'json'�� return unless options[:app_rating_config_path]� def set_app_rating(version, options)�� end� end� UI.message("Removing review attachment file to App Store Connect") unless app_store_review_attachments.empty?� app_store_review_attachments.each(&:delete!)� else� app_store_review_detail.upload_attachment(path: options[:app_review_attachment_file])� UI.message("Uploading review attachment file to App Store Connect")�� end� app_store_review_attachment.delete!� UI.message("Removing previous review attachment file from App Store Connect")� app_store_review_attachments.each do |app_store_review_attachment|� if options[:app_review_attachment_file]�� app_store_review_attachments = app_store_review_detail.app_store_review_attachments || []� app_store_review_detail = version.fetch_app_store_review_detail� def set_review_attachment_file(version, options)�� end� end� version.create_app_store_review_detail(attributes: attributes)�ad������b�����T�����������������������������n��O����� ��� �� ��Y ��9 ��������4��%����������������~��}��a��7����� ��� ��� ��5 �� ��� ��� ��k ��] ��: ��������������������N��'���������������������m��M�����������������K��*��������������\��[��'�����������X����������������W��������b��9����������������������������������������������������������������������������������� language = File.basename(lang_folder)� next language = File.basename(lang_folder)� next u language = File.basename(lang_fol language = File.basename(lang_folder)� next unless File.directory?(lang_folder) # We don't want to read txt as they are non localised� Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|� ignore_validation = options[:ignore_language_directory_validation]� # Check folder list (an empty folder signifies a language is required)�� end� end� enabled_languages << language unless enabled_languages.include?(language)� current.each do |language, value|� next unless current && current.kind_of?(Hash)� current = options[key]� (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|� # Get all languages used in existing settings�� enabled_languages = detect_languages(options)� # Build a complete list of the required languages�� normalize_language_keys(options)� # Normalizes languages keys from symbols to strings� def assign_defaults(options)� # If the user is using the 'default' language, then assign values where they are needed�� end� return Time.at(time_in_s_to_hour).utc.strftime("%Y-%m-%dT%H:%M:%S%:z")�� time_in_s_to_hour = (time_in_s / seconds_in_hour).to_i * seconds_in_hour� seconds_in_hour = 60 * 60� # Remove minutes and seconds (whole hour)�� time_in_s = time_in_ms / 1000� def convert_ms_to_iso8601(time_in_ms)�� # rubocop:enable Metrics/PerceivedComplexity�� end� set_app_rating(version, options)� set_review_attachment_file(version, options)� set_review_information(version, options)�� end� end� reset_rating_request.delete!� UI.message("Removing reset ratings request on App Store Connect")� elsif reset_rating_request� end� version.create_reset_ratings_request� UI.message("Creating reset ratings request on App Store Connect")� unless reset_rating_request� if !!options[:reset_ratings]� end # returns no data error so need to rescue� nil� rescue� version.fetch_reset_ratings_request� reset_rating_request = begin� unless options[:reset_ratings].nil?� # Update rating reset�� end� end� phased_release.delete!� UI.message("Removing phased release on App Store Connect")� elsif phased_release� end� })� phasedReleaseState: Spaceship::ConnectAPI::AppStoreVersionPhasedRelease::PhasedReleaseState::INACTIVE� version.create_app_store_version_phased_release(attributes: {� UI.message("Creating phased release on App Store Connect")� unless phased_release� if !!options[:phased_release]� end # returns no data error so need to rescue� nil� rescue� version.fetch_app_store_version_phased_release� phased_release = begin� unless options[:phased_release].nil?� # Update phased release�� end� app_info.update_categories(category_id_map: category_id_map)�� UI.deprecated("You can find more info at https://docs.fastlane.tools/actions/deliver/#reference") if has_mapped_values� end� UI.deprecated("Category '#{k}' from iTunesConnect as been deprecated. Please replace with '#{v}'")�ad�����������c�������������i��#����������������������[��Q��P��5��-��,��� ��� ��� ��� ��z ��1 ��������Q����������������r��f��\��[��;��� ��� ��� ��� ��V ��- ��# ��" �� ��� ��� ��9 �� �����������O��E��=��<��0��/��������~��_��)��(��������������������������e��0����������v��8�� �����������Q�� ����������������h�� ��������b��$������������������������������ else� app_store_review_detail.update(attributes: attributes)� if app_store_review_detail� end # errors if doesn't exist� nil� UI.error("Error fetching app store review detail - #{error.message}")� rescue => error� version.fetch_app_store_review_detail� app_store_review_detail = begin� UI.message("Uploading app review information to App Store Connect")�� end� attributes["demoAccountRequired"] = false� else� attributes["demoAccountRequired"] = true� if !attributes["demoAccountName"].to_s.empty? && !attributes["demoAccountPassword"].to_s.empty?�� end� attributes[attribute_name] = strip_value unless strip_value.empty?� strip_value = info[key].to_s.strip� REVIEW_INFORMATION_VALUES.each do |key, attribute_name|� attributes = {}�� UI.user_error!("`app_review_information` must be a hash", show_github_issues: true) unless info.kind_of?(Hash)� info = options[:app_review_information]� return unless options[:app_review_information]� def set_review_information(version, options)�� end� options�� end� end� current[language.to_s] = current.delete(language)� current.keys.each do |language|�� next unless current && current.kind_of?(Hash)� current = options[key]� (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|� def normalize_language_keys(options)� # Normalizes languages keys from symbols to strings�� private�� end� end� options[:app_review_information][option_name] ||= File.read(path)� UI.message("Loading '#{path}'...")�� next if options[:app_review_information][option_name].to_s.length > 0� next unless File.exist?(path)� path = File.join(options[:metadata_path], REVIEW_INFORMATION_DIR, "#{option_name}.txt")� REVIEW_INFORMATION_VALUES.keys.each do |option_name|� options[:app_review_information] ||= {}� # Load review information�� end� options[key] ||= File.read(path)� UI.message("Loading '#{path}'...")�� next unless File.exist?(path)� path = File.join(options[:metadata_path], "#{key}.txt")� (NON_LOCALISED_VERSION_VALUES.keys + NON_LOCALISED_APP_VALUES).each do |key|� # Load non localised data�� end� end� options[key][language] ||= File.read(path)� options[key] ||= {}� UI.message("Loading '#{path}'...")�� next unless File.exist?(path)� path = File.join(lang_folder, "#{key}.txt")� (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|� language = File.basename(lang_folder)� Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|� ignore_validation = options[:ignore_language_directory_validation]� # Load localised data�� return if options[:skip_metadata]� def load_from_filesystem(options)� # Loads the metadata files and stores them into the options object�� end� return localizations�� end� localizations = version.get_app_store_version_localizations� # Refresh version localizations�� Helper.hide_loading_indicator�� end� })� locale: locale� version.create_app_store_version_localization(attributes: {� locales_to_enable.each do |locale|�� Helper.show_loading_indicator("Activating version #{lng_text} #{locales_to_enable.join(', ')}...")�ad��7���������T����������J��)����������������=��� ��� ��� ��� ��I �� ��������8��7����������������t��s��M��� ��� ��� ��� ��� ��E ��6 ��* ��) ��� ��� ��� ��� ��^ ��# ��" ��������u��t��$�����������Y��M��C��B����������������@����������������o��%�����������N��������f��L��������������k�������������������������������������������������������������������� if attributes� attributes = localized_version_attributes_by_locale[app_store_version_localization.locale]� app_store_version_localizations.each do |app_store_version_localization|� # Update app store version localizations�� non_localized_version_attributes['releaseType'] = release_type� end� Spaceship::ConnectAPI::AppStoreVersion::ReleaseType::MANUAL� else� Spaceship::ConnectAPI::AppStoreVersion::ReleaseType::AFTER_APPROVAL� elsif options[:automatic_release]� Spaceship::ConnectAPI::AppStoreVersion::ReleaseType::SCHEDULED� non_localized_version_attributes['earliestReleaseDate'] = date�� date = convert_ms_to_iso8601(time_in_ms)� time_in_ms = options[:auto_release_date]� # Convert time format to 2020-06-17T12:00:00-07:00� release_type = if options[:auto_release_date]�� end� end� non_localized_version_attributes[attribute_name] = strip_value� attribute_name = NON_LOCALISED_VERSION_VALUES[key]� if NON_LOCALISED_VERSION_VALUES.include?(key) && !strip_value.empty?�� next unless strip_value.to_s.length > 0� strip_value = options[key].to_s.strip� non_localised_options.each do |key|� non_localized_version_attributes = {}�� end� end� localized_info_attributes_by_locale[language][attribute_name] = strip_value� localized_info_attributes_by_locale[language] ||= {}�� attribute_name = LOCALISED_APP_VALUES[key]� next unless LOCALISED_APP_VALUES.include?(key) && !strip_value.empty?�� end� localized_version_attributes_by_locale[language][attribute_name] = strip_value� localized_version_attributes_by_locale[language] ||= {}�� attribute_name = LOCALISED_VERSION_VALUES[key]� if LOCALISED_VERSION_VALUES.include?(key) && !strip_value.empty?�� strip_value = value.to_s.strip� next unless value.to_s.length > 0� current.each do |language, value|�� end� next� UI.error("Skipping 'release_notes'... this is the first version of the app")� if key == :release_notes && is_first_version�� end� next� UI.error("Error with provided '#{key}'. Must be a hash, the key being the language.")� unless current.kind_of?(Hash)�� next unless current� current = options[key]� localised_options.each do |key|�� localized_info_attributes_by_locale = {}� localized_version_attributes_by_locale = {}�� UI.important("Will begin uploading metadata for '#{version.version_string}' on App Store Connect")�� UI.verbose("Version '#{version.version_string}' is the first version on App Store Connect") if is_first_version� is_first_version = number_of_versions == 1� number_of_versions = app.get_app_store_versions(filter: { platform: platform }, limit: 2).size� # Needed for to filter out release notes from being sent up�� end� non_localised_options = NON_LOCALISED_VERSION_VALUES.keys� localised_options = (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys)� version = app.get_edit_app_store_version(platform: platform)� else� end� UI.message("Found live version")� else� # in the documentation� # by not touching those 2 variables, deliver is more consistent with what the option says� # as we also check for `options[:edit_live]` at other areas in the code�ad�����������\���������7��+��!�� ��������f��P��� ��� ��� ��� ��� ��d �� �����������������f��e��$��������3��� �� ��~ ��c ��b �� ��� ��� ��� �� ��~ ��K �� �� ��������q��e��d��/�����������������6��������������y��R����������������O��C��B����������d��X��W�������������Q��'������������������O��-��������������������������������������������� has_mapped_values = true� next if k == v� next if k.nil? || v.nil?� mapped_values.each do |k, v|� has_mapped_values = false� # Print deprecation warnings if category was mapped�� end� category_id_map[:secondary_subcategory_two_id] = mapped� mapped_values[secondary_second_sub_category] = mapped�� )� secondary_second_sub_category� mapped = Spaceship::ConnectAPI::AppCategory.map_subcategory_from_itc(� unless secondary_category.empty?� end� category_id_map[:secondary_subcategory_one_id] = mapped� mapped_values[secondary_first_sub_category] = mapped�� )� secondary_first_sub_category� mapped = Spaceship::ConnectAPI::AppCategory.map_subcategory_from_itc(� unless secondary_category.empty?� # Only set if secondary category is going to be set�� end� category_id_map[:primary_subcategory_two_id] = mapped� mapped_values[primary_second_sub_category] = mapped�� )� primary_second_sub_category� mapped = Spaceship::ConnectAPI::AppCategory.map_subcategory_from_itc(� unless primary_category.empty?� end� category_id_map[:primary_subcategory_one_id] = mapped� mapped_values[primary_first_sub_category] = mapped�� )� primary_first_sub_category� mapped = Spaceship::ConnectAPI::AppCategory.map_subcategory_from_itc(� unless primary_category.empty?� # Only set if primary category is going to be set�� end� category_id_map[:secondary_category_id] = mapped� mapped_values[secondary_category] = mapped�� )� secondary_category� mapped = Spaceship::ConnectAPI::AppCategory.map_category_from_itc(� unless secondary_category.empty?� end� category_id_map[:primary_category_id] = mapped� mapped_values[primary_category] = mapped�� )� primary_category� mapped = Spaceship::ConnectAPI::AppCategory.map_category_from_itc(� unless primary_category.empty?� # Only update primary and secondar category if explicitly set�� mapped_values = {}�� secondary_second_sub_category = options[:secondary_second_sub_category].to_s.strip� secondary_first_sub_category = options[:secondary_first_sub_category].to_s.strip� primary_second_sub_category = options[:primary_second_sub_category].to_s.strip� primary_first_sub_category = options[:primary_first_sub_category].to_s.strip� secondary_category = options[:secondary_category].to_s.strip� primary_category = options[:primary_category].to_s.strip�� category_id_map = {}� if app_info� app_info = app.fetch_edit_app_info� # Update categories�� version.update(attributes: non_localized_version_attributes)� UI.message("Uploading metadata to App Store Connect for version")� # Update app store version�� end� end� app_info_localization.update(attributes: attributes)� UI.message("Uploading metadata to App Store Connect for localized info '#{app_info_localization.locale}'")� if attributes� attributes = localized_info_attributes_by_locale[app_info_localization.locale]� app_info_localizations.each do |app_info_localization|� # Update app info localizations�� end� end� app_store_version_localization.update(attributes: attributes)� UI.message("Uploading metadata to App Store Connect for localized version '#{app_store_version_localization.locale}'")�ad��T��������g����������������i��'��&��������������[��>��=����� ��� ��� ��� ��� ��v ��l ��d ��c ��A �� �����������P��1��������}��q��g��f����� ��p �� �� ��� ��� ��~ ��} ��9 ��! �� �����������������h��g��Q��������������������`���������������:��9�������������������u��t��L��������������������z��1�����������o��`��V��U���������������b��D������������������������������������������������������������������������������������������ lng_text += "s" if locales_to_enable.count != 1� lng_text = "language"� if locales_to_enable.count > 0�� locales_to_enable = languages - localizations.map(&:locale)� languages = (languages || []).reject { |lang| lang == "default" }�� localizations = version.get_app_store_version_localizations�� end� return� UI.user_error!("Cannot update languages - could not find an editable version for '#{platform}'")� unless version�� version = app.get_edit_app_store_version(platform: platform)� platform = Spaceship::ConnectAPI::Platform.map(options[:platform])� def verify_available_version_languages!(options, app, languages)� # Finding languages to enable�� end� return localizations�� end� localizations = app_info.get_app_info_localizations� # Refresh version localizations�� Helper.hide_loading_indicator�� end� })� locale: locale� app_info.create_app_info_localization(attributes: {� locales_to_enable.each do |locale|�� Helper.show_loading_indicator("Activating info #{lng_text} #{locales_to_enable.join(', ')}...")� lng_text += "s" if locales_to_enable.count != 1� lng_text = "language"� if locales_to_enable.count > 0�� locales_to_enable = languages - localizations.map(&:locale)� languages = (languages || []).reject { |lang| lang == "default" }�� localizations = app_info.get_app_info_localizations�� end� return� UI.user_error!("Cannot update languages - could not find an editable info")� unless app_info�� app_info = app.fetch_edit_app_info� def verify_available_info_languages!(options, app, languages)� # Finding languages to enable�� end� .uniq� .map(&:to_s)� enabled_languages� # Mapping to strings because :default symbol can be passed in�� end� enabled_languages << language unless enabled_languages.include?(language)� language = File.basename(lang_folder)�� next unless File.directory?(lang_folder) # We don't want to read txt as they are non localised� Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|� ignore_validation = options[:ignore_language_directory_validation]� # Check folder list (an empty folder signifies a language is required)�� end� end� enabled_languages << language unless enabled_languages.include?(language)� current.each do |language, value|� next unless current && current.kind_of?(Hash)� current = options[key]� (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|� # Get all languages used in existing settings�� enabled_languages = options[:languages] || []� # Build a complete list of the required languages� def detect_languages(options)�� end� end� current.delete("default")� end� current[language] = default�� next unless value.nil?� value = current[language]� enabled_languages.each do |language|�� next if default.nil?� default = current["default"]�� next unless current && current.kind_of?(Hash)� current = options[key]� (LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|�� UI.message("Detected languages: " + enabled_languages.to_s)� return unless enabled_languages.include?("default")�� end� enabled_languages << language unless enabled_languages.include?(language)�