<file_sep>import Foundation

public extension Object {
    /// объект, описывающий видеозапись
    public struct Video: Codable {
        /// ключ доступа к объекту
        public let access_key: String?
        /// идентификатор альбома, в котором находится видеозапись
        public let album_id: Int?
        /// дата добавления видеозаписи пользователем или группой в формате Unixtime
        public let adding_date: Int?
        /// если пользователь может добавить видеозапись к себе
        public let can_add: Object.Boolean?
        /// поле возвращается, если пользователь может редактировать видеозапись
        public let can_edit: Object.Positive?
        /// количество комментариев к видеозаписи
        public let comments: Int?
        /// запрещенный контент
        public let content_restricted: Object.Positive?
        /// дата создания видеозаписи в формате Unixtime
        public let date: Int?
        /// текст описания видеозаписи
        public let description: String
        /// длительность ролика в секундах
        public let duration: Int?
        /// URL первого фрейма ролика с размером 130x98 px
        public let first_frame_130: String?
        /// URL первого фрейма ролика с размером 160x120 px
        public let first_frame_160: String?
        /// URL первого фрейма ролика с размером 320x240 px
        public let first_frame_320: String?
        /// URL первого фрейма ролика с размером 800x450 px
        public let first_frame_800: String?
        /// высота
        public let height: Int?
        /// идентификатор видеозаписи
        public let id: Int
        /// приватное
        public let is_private: Object.Positive?
        /// видеозапись является прямой трансляцией
        public let live: Object.Positive?
        /// идентификатор владельца видеозаписи
        public let owner_id: Int
        /// URL изображения-обложки ролика с размером 130x98 px
        public let photo_130: String?
        /// URL изображения-обложки ролика с размером 320x240 px
        public let photo_320: String?
        /// URL изображения-обложки ролика с размером 640x480 px
        public let photo_640: String?
        /// URL изображения-обложки ролика с размером 800x450 px
        public let photo_800: String?
        /// название платформы (для видеозаписей, добавленных с внешних сайтов)
        public let platform: String?
        /// URL страницы с плеером, который можно использовать для воспроизведения ролика в браузере. Поддерживается flash и html5, плеер всегда масштабируется по размеру окна
        public let player: String?
        /// видеоролик находится в процессе обработки
        public let processing: Object.Positive?
        /// повторять видеозапись
        public let `repeat`: Object.Positive?
        /// название видеозаписи
        public let title: String
        /// трансляция скоро начнётся
        public let upcoming: Object.Positive?
        /// идентификатор пользователя
        public let user_id: Int?
        /// количество просмотров видеозаписи
        public let views: Int?
        /// ширина
        public let width: Int?
    }
}

<file_sep>import RxCocoa
import RxSwift
import UIKit
import VK

extension VK.Service {
    
    func observableRequest<C, S, T>(cancel: Observable<C>, delay: TimeInterval = 0, lang: String = "ru", logs: Logs = .none, queue: DispatchQueue = .global(), strategy: S, timeout: TimeInterval = 10, track: Bool = true, v: String = "5.80") -> Observable<Output<T>> where S: Strategy, S.Value == T {
        return request(cancel: cancel, delay: delay, lang: lang, logs: logs, queue: queue, strategy: strategy, timeout: timeout, track: track, v: v)
    }
    
    func observableRequest<S, T>(delay: TimeInterval = 0, lang: String = "ru", logs: Logs = .none, queue: DispatchQueue = .global(), strategy: S, timeout: TimeInterval = 10, track: Bool = true, v: String = "5.80") -> Observable<Output<T>> where S: Strategy, S.Value == T {
        let cancel = Observable<Void>.never()
        return request(cancel: cancel, delay: delay, lang: lang, logs: logs, queue: queue, strategy: strategy, timeout: timeout, track: track, v: v)
    }
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    let disposeBag = DisposeBag()
    var window: UIWindow?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
        defer {
            let strategy = Method.Utils.GetServerTime(token: "c0ece882f55b39c5899af7065b923ed55bcb96ade6e52aa2693d0ea674c41063a2decc1616604739d8cd7")
            getService()
                .observableRequest(strategy: strategy)
                .debug()
                .subscribe()
                .disposed(by: disposeBag)
        }
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = UINavigationController(rootViewController: UIViewController())
        window?.makeKeyAndVisible()
        return true
    }
}
<file_sep>import Foundation
/// стратегия запроса к API
public protocol Strategy {
    /// ассоциированное занчение, которое соответствует исходному ответу
    associatedtype Raw: Decodable
    /// ассоциированное занчение, к которому должен быть приобразован финальный ответ
    associatedtype Value: Decodable
    /// трансформация из исходного ответа в финальный
    var transform: (Raw) -> Value { get }
    /// название метода API, к которому Вы хотите обратиться
    var method: String { get }
    /// входные параметры соответствующего метода API
    var parameters: [String: Any] { get }
}
<file_sep>use_frameworks!
platform :ios, '10.0'

target 'Auth' do
    pod 'VK', :path => '../'
end

post_install do |installer|
    installer.pods_project.targets.each do |target|
        target.build_configurations.each do |config|
            config.build_settings['SWIFT_VERSION'] = '4.1'
        end
    end
end
<file_sep>import Foundation

public extension Object {
    /// объект описывающий сокращенную ссылку для текущего пользователя
    public struct ShortenedLink: Decodable, Hashable {

        public var hashValue: Int {
            return key.hashValue
        }
        
        enum CodingKeys: String, CodingKey {
            
            case accessKey = "access_key"
            case key = "key"
            case shortUrl = "short_url"
            case timestamp = "timestamp"
            case url = "url"
            case views = "views"
        }
        /// ключ доступа к приватной статистике
        public let accessKey: String?
        /// содержательная часть (символы после "vk.cc")
        public let key: String
        /// сокращенный URL
        public let shortUrl: String
        /// время создания ссылки в Unixtime
        public let timestamp: TimeInterval
        /// URL ссылки до сокращения
        public let url: String
        /// число переходов
        public let views: Int
        
        public init(accessKey: String?, key: String, shortUrl: String, timestamp: TimeInterval, url: String, views: Int) {
            self.accessKey = accessKey
            self.key = key
            self.shortUrl = shortUrl
            self.timestamp = timestamp
            self.url = url
            self.views = views
        }
    }
}
<file_sep>import Foundation

public extension Object {
    ///
    public enum Target: Codable {
        /// внутренний
        case `internal`
        /// неизвестное значение
        case exception(String)
        
        init(rawValue: String) {
            switch rawValue {
            case "internal":
                self = .internal
            default:
                self = .exception(rawValue)
            }
        }
        
        public var rawValue: String {
            switch self {
            case .internal:
                return "internal"
            case .exception(let value):
                return value
            }
        }
        
        public init(from decoder: Decoder) throws {
            var container = try decoder.singleValueContainer()
            let rawValue: String = try container.decode()
            self = Object.Target(rawValue: rawValue)
        }
        
        public func encode(to encoder: Encoder) throws {
            var container = encoder.singleValueContainer()
            try container.encode(rawValue)
        }
    }
}

<file_sep>import Foundation

public extension Object {
    /// объект описывающий данные о статистике
    public struct ShortenedLinkStats: Codable {
        /// геостатистика по городам
        public struct City: Codable {
            /// идентификатор города;
            public let city_id: Int?
            private let _city_id: String?
            /// число переходов из этого города
            public let views: Int
            
            private enum Key: String, CodingKey {
                case city_id
                case views
            }
            
            public init(from decoder: Decoder) throws {
                let container = try Key.container(decoder: decoder)
                views = try container.decode(key: Key.views)
                do {
                    self.city_id = try container.decode(key: Key.city_id)
                    self._city_id = nil
                } catch {
                    self.city_id = nil
                    self._city_id = try container.decodeIfPresent(String.self, forKey: Key.city_id)
                }
            }
            
            public func encode(to encoder: Encoder) throws {
                var encoder = Key.container(encoder: encoder)
                try encoder.encode(views, forKey: Key.views)
                if let city_id = self.city_id {
                    try encoder.encode(city_id, forKey: Key.city_id)
                } else if let city_id = self._city_id {
                    try encoder.encode(city_id, forKey: Key.city_id)
                }
            }
        }
        /// геостатистика по странам
        public struct Country: Codable {
            /// идентификатор страны
            public let country_id: Int?
            private let _country_id: String?
            /// число переходов из этой страны
            public let views: Int
            
            private enum Key: String, CodingKey {
                case country_id
                case views
            }
            
            public init(from decoder: Decoder) throws {
                let container = try Key.container(decoder: decoder)
                views = try container.decode(key: Key.views)
                do {
                    self.country_id = try container.decode(key: Key.country_id)
                    self._country_id = nil
                } catch {
                    self.country_id = nil
                    self._country_id = try container.decodeIfPresent(String.self, forKey: Key.country_id)
                }
            }
            
            public func encode(to encoder: Encoder) throws {
                var encoder = Key.container(encoder: encoder)
                try encoder.encode(views, forKey: Key.views)
                if let country_id = self.country_id {
                    try encoder.encode(country_id, forKey: Key.country_id)
                } else if let country_id = self._country_id {
                    try encoder.encode(country_id, forKey: Key.country_id)
                }
            }
        }
        /// половозрастная статистика
        public struct SexAge: Codable {
            /// обозначение возраста
            public let age_range: String
            /// число переходов пользователей женского пола
            public let female: Int
            /// число переходов пользователей мужского пола
            public let male: Int
        }
        /// геостатистику по городам
        public let cities: [Object.ShortenedLinkStats.City]?
        /// геостатистику по странам
        public let countries: [Object.ShortenedLinkStats.Country]?
        /// половозрастная статистика
        public let sex_age: [Object.ShortenedLinkStats.SexAge]?
        /// время создания ссылки в Unixtime
        public let timestamp: Int
        /// число переходов
        public let views: Int
    }
}
<file_sep>import Foundation

public extension Object {
    /// медиавложение в записях на стене
    public enum Attachment: Codable {
        /// тип вложения
        public enum Typе: String, Codable {
            /// альбом с фотографиями
            case album
            /// контент приложения. Это устаревший тип вложений
            case app
            /// аудиозапись
            case audio
            /// документ
            case doc
            /// граффити. Это устаревший тип вложения
            case graffiti
            /// ссылка
            case link
            /// товар
            case market
            /// подборка товаров
            case market_album
            /// заметка
            case note
            /// вики-страница
            case page
            /// фотография
            case photo
            /// список фотографий
            case photos_list
            /// опрос
            case poll
            /// фотография, загруженная напрямую. Это устаревший тип вложения
            case posted_photo
            /// pretty_cards
            case pretty_cards
            /// стикер
            case sticker
            /// видеозапись
            case video
        }
        
        private enum Key: String, CodingKey {
            case album, app, audio, doc, graffiti, link, market, market_album, note, page, photo, photos_list, poll, posted_photo, pretty_cards, sticker, video, type
        }
        
        /// объект, описывающий альбом с фотографиями
        case album(Object.Album)
        /// объект, описывающий контент приложения
        case app(Object.App)
        /// объект, описывающий аудиозапись
        case audio(Object.Audio)
        /// объект, описывающий документ
        case doc(Object.Doc)
        /// объект, описывающий граффити
        case graffiti(Object.Graffiti)
        /// объект, описывающий прикрепленную ссылку
        case link(Object.Link)
        /// объект, описывающий товар
        case market(Object.MarketItem)
        /// объект, описывающий подборку товаров
        case market_album(Object.MarketAlbum)
        /// объект, описывающий заметку
        case note(Object.Note)
        /// объект, описывающий вики-страницу
        case page(Object.Page)
        /// объект, описывающий фотографию
        case photo(Object.Photo)
        /// список фотографий
        case photos_list([String]?)
        /// объект, описывающий опрос
        case poll(Object.Poll)
        /// объект, описывающий фотографию, загруженную напрямую
        case posted_photo(Object.PostedPhoto)
        /// карусель товаров
        case pretty_cards(Object.PrettyCards)
        /// объект, описывающий стикер
        case sticker(Object.Sticker)
        /// объект, описывающий видеозапись
        case video(Object.Video)
        
        public init(from decoder: Decoder) throws {
            let container = try Key.container(decoder: decoder)
            let type: Object.Attachment.Typе = try container.decode(key: Key.type)
            switch type {
            case .album:
                let album: Object.Album = try container.decode(key: Key.album)
                self = .album(album)
            case .app:
                let app: Object.App = try container.decode(key: Key.app)
                self = .app(app)
            case .audio:
                let audio: Object.Audio = try container.decode(key: Key.audio)
                self = .audio(audio)
            case .doc:
                let doc: Object.Doc = try container.decode(key: Key.doc)
                self = .doc(doc)
            case .graffiti:
                let graffiti: Object.Graffiti = try container.decode(key: Key.graffiti)
                self = .graffiti(graffiti)
            case .link:
                let link: Object.Link = try container.decode(key: Key.link)
                self = .link(link)
            case .market:
                let market: Object.MarketItem = try container.decode(key: Key.market)
                self = .market(market)
            case .market_album:
                let market_album: Object.MarketAlbum = try container.decode(key: Key.market_album)
                self = .market_album(market_album)
            case .note:
                let note: Object.Note = try container.decode(key: Key.note)
                self = .note(note)
            case .page:
                let page: Object.Page = try container.decode(key: Key.page)
                self = .page(page)
            case .photo:
                let photo: Object.Photo = try container.decode(key: Key.photo)
                self = .photo(photo)
            case .photos_list:
                let photos_list: [String]? = try container.decode(key: Key.photos_list)
                self = .photos_list(photos_list)
            case .poll:
                let poll: Object.Poll = try container.decode(key: Key.poll)
                self = .poll(poll)
            case .posted_photo:
                let posted_photo: Object.PostedPhoto = try container.decode(key: Key.posted_photo)
                self = .posted_photo(posted_photo)
            case .pretty_cards:
                let pretty_cards: Object.PrettyCards = try container.decode(key: Key.pretty_cards)
                self = .pretty_cards(pretty_cards)
            case .sticker:
                let sticker: Object.Sticker = try container.decode(key: Key.sticker)
                self = .sticker(sticker)
            case .video:
                let video: Object.Video = try container.decode(key: Key.video)
                self = .video(video)
            }
        }
        
        public func encode(to encoder: Encoder) throws {
            var container = Key.container(encoder: encoder)
            switch self {
            case .app(let app):
                try container.encode(Key.app.rawValue, forKey: Key.type)
                try container.encode(app, forKey: Key.app)
            case .album(let album):
                try container.encode(Key.album.rawValue, forKey: Key.type)
                try container.encode(album, forKey: Key.album)
            case .audio(let audio):
                try container.encode(Key.audio.rawValue, forKey: Key.type)
                try container.encode(audio, forKey: Key.audio)
            case .doc(let doc):
                try container.encode(Key.doc.rawValue, forKey: Key.type)
                try container.encode(doc, forKey: Key.doc)
            case .graffiti(let graffiti):
                try container.encode(Key.graffiti.rawValue, forKey: Key.type)
                try container.encode(graffiti, forKey: Key.graffiti)
            case .link(let link):
                try container.encode(Key.link.rawValue, forKey: Key.type)
                try container.encode(link, forKey: Key.link)
            case .market(let market):
                try container.encode(Key.market.rawValue, forKey: Key.type)
                try container.encode(market, forKey: Key.market)
            case .market_album(let market_album):
                try container.encode(Key.market_album.rawValue, forKey: Key.type)
                try container.encode(market_album, forKey: Key.market_album)
            case .note(let note):
                try container.encode(Key.note.rawValue, forKey: Key.type)
                try container.encode(note, forKey: Key.note)
            case .page(let page):
                try container.encode(Key.page.rawValue, forKey: Key.type)
                try container.encode(page, forKey: Key.page)
            case .photo(let photo):
                try container.encode(Key.photo.rawValue, forKey: Key.type)
                try container.encode(photo, forKey: Key.photo)
            case .photos_list(let photos_list):
                try container.encode(Key.photos_list.rawValue, forKey: Key.type)
                try container.encode(photos_list, forKey: Key.photos_list)
            case .poll(let poll):
                try container.encode(Key.poll.rawValue, forKey: Key.type)
                try container.encode(poll, forKey: Key.poll)
            case .posted_photo(let posted_photo):
                try container.encode(Key.posted_photo.rawValue, forKey: Key.type)
                try container.encode(posted_photo, forKey: Key.posted_photo)
            case .pretty_cards(let pretty_cards):
                try container.encode(Key.pretty_cards.rawValue, forKey: Key.type)
                try container.encode(pretty_cards, forKey: Key.pretty_cards)
            case .video(let video):
                try container.encode(Key.video.rawValue, forKey: Key.type)
                try container.encode(video, forKey: Key.video)
            case .sticker(let sticker):
                try container.encode(Key.sticker.rawValue, forKey: Key.type)
                try container.encode(sticker, forKey: Key.sticker)
            }
        }
    }
}
<file_sep>import Foundation

public extension Object {
    /// граффити
    public struct Graffiti: Codable {
        /// идентификатор граффити
        public let id: Int?
        /// идентификатор автора граффити
        public let owner_id: Int?
        /// URL изображения для предпросмотра
        public let photo_130: String?
        /// URL изображения для предпросмотра
        public let photo_200: String?
        /// URL изображения для предпросмотра
        public let photo_586: String?
        /// URL полноразмерного изображения
        public let photo_604: String?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий подборку товаров
    public struct MarketAlbum: Codable {
        /// число товаров в подборке
        public let count: Int?
        /// идентификатор подборки
        public let id: Int?
        /// обложка подборки
        public let photo: Object.Photo?
        /// идентификатор владельца подборки
        public let owner_id: Int?
        /// название подборки
        public let title: String?
        /// дата обновления подборки в формате Unixtime
        public let updated_time: Int?
    }
}
<file_sep>import Foundation

public extension Method.Utils {
    /// список сокращенных ссылок для текущего пользователя
    public struct GetLastShortenedLinks: Strategy {
        /// количество ссылок, которые необходимо получить
        public let count: Int
        /// сдвиг для получения определенного подмножества ссылок
        public let offset: Int
        /// пользовательские данные
        public let token: Token

        public init(count: Int = 10, offset: Int = 0, token: Token) {
            self.count = count
            self.offset = offset
            self.token = token
        }

        public var method: String {
            return "utils.getLastShortenedLinks"
        }
        
        public var parameters: [String : Any] {
            var dictionary = [String : Any]()
            dictionary["access_token"] = token
            dictionary["count"] = "\(count)"
            dictionary["offset"] = "\(offset)"
            return dictionary
        }
        
        public var transform: (Object.Response<Object.Items<Object.ShortenedLink>>) -> [Object.ShortenedLink] {
            return { $0.response.items }
        }
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект product, описывающий информацию о продукте
    public struct Product: Codable {
        /// объект price, описывающий цену
        public struct Price: Codable {
            /// объект currency, описывающий информацию о валюте
            public struct Currency: Codable {
                /// идентификатор валюты
                public let id: Int?
                /// буквенное обозначение валюты
                public let name: String?
            }
            /// целочисленное значение цены, умноженное на 100
            public let amount: String?
            /// объект currency
            public let currency: Object.Product.Price.Currency?
            /// строка с локализованной ценой и валютой
            public let text: String?
        }
        /// объект price
        public let price: Object.Product.Price?
    }
}
<file_sep>import Foundation

public extension Object {
    /// сообщество
    public struct Group: Codable {
        /// информация о том, является ли текущий пользователь руководителем
        public enum AdminLevel: Codable {
            /// модератор
            case moderator
            /// редактор
            case editor
            /// администратор
            case administrator
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 1:
                    self = .moderator
                case 2:
                    self = .editor
                case 3:
                    self = .administrator
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .moderator:
                    return 1
                case .editor:
                    return 2
                case .administrator:
                    return 3
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Group.AdminLevel(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// возрастное ограничение
        public enum AgeLimits: Codable {
            /// нет
            case none
            /// 16+
            case above16
            /// 18+
            case above18
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 1:
                    self = .none
                case 2:
                    self = .above16
                case 3:
                    self = .above18
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .none:
                    return 1
                case .above16:
                    return 2
                case .above18:
                    return 3
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Group.AgeLimits(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// информация о занесении в черный список сообщества
        public struct BanInfo: Codable {
            /// комментарий к блокировке
            public let comment: String?
            /// срок окончания блокировки в формате unixtime
            public let end_date: Int?
        }
        /// информация из блока контактов публичной страницы
        public struct Contact: Codable {
            /// должность
            public let desc: String?
            /// адрес e-mail
            public let email: String?
            /// номер телефона
            public let phone: String?
            /// идентификатор пользователя
            public let user_id: Int?
        }
        /// объект, содержащий счётчики сообщества
        public struct Counters: Codable {
            /// количество фотоальбомов
            public let albums: Int?
            /// количество аудиозаписей
            public let audios: Int?
            /// количество документов
            public let docs: Int?
            /// количество фотографий
            public let photos: Int?
            /// количество обсуждений
            public let topics: Int?
            /// количество видеозаписей
            public let videos: Int?
        }
        /// обложка сообщества
        public struct Cover: Codable {
            /// включена ли обложка
            public let enabled: Object.Boolean?
            /// копии изображений обложки
            public let images: [Object.Image]?
        }
        /// возвращается в случае, если сообщество удалено или заблокировано
        public enum Deactivated: String, Codable {
            /// сообщество заблокировано
            case banned
            /// сообщество удалено
            case deleted
        }
        /// является ли сообщество закрытым
        public enum IsClosed: Codable {
            /// открытое
            case opened
            /// закрытое
            case closed
            /// частное
            case `private`
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .opened
                case 1:
                    self = .closed
                case 2:
                    self = .private
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .opened:
                    return 0
                case .closed:
                    return 1
                case .private:
                    return 2
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Group.IsClosed(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// информация из блока ссылок сообщества
        public struct Link: Codable {
            /// описание ссылки
            public let desc: String?
            /// идентификатор ссылки
            public let id: Int?
            /// название ссылки
            public let name: String?
            /// URL изображения-превью шириной 100px
            public let photo_100: String?
            /// URL изображения-превью шириной 50px
            public let photo_50: String?
            /// URL
            public let url: String?
        }
        /// информация о главной секции
        public enum MainSection: Codable {
            /// отсутствует
            case no_main_section
            /// фотографии
            case photos
            /// обсуждения
            case topics
            /// аудиозаписи
            case audios
            /// видеозаписи
            case videos
            /// товары
            case market
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .no_main_section
                case 1:
                    self = .photos
                case 2:
                    self = .topics
                case 3:
                    self = .audios
                case 4:
                    self = .videos
                case 5:
                    self = .market
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .no_main_section:
                    return 0
                case .photos:
                    return 1
                case .topics:
                    return 2
                case .audios:
                    return 3
                case .videos:
                    return 4
                case .market:
                    return 5
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Group.MainSection(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// информация о магазине
        public struct Market: Codable {
            /// информация о валюте
            public struct Currency: Codable {
                /// идентификатор валюты
                public let id: Int?
                /// символьное обозначение
                public let name: String?
            }
            /// идентификатор контактного лица для связи с продавцом. Возвращается отрицательное значение, если для связи с продавцом используются сообщения сообщества
            public let contact_id: Int?
            /// строковое обозначение валюты
            public let currency_text: String?
            /// информация о том, включен ли блок товаров в сообществе
            public let enabled: Object.Boolean?
            /// идентификатор главной подборки товаров
            public let main_album_id: Int?
            /// максимальная цена товаров
            public let price_max: Int?
            /// минимальная цена товаров
            public let price_min: Int?
        }
        /// статус участника текущего пользователя
        public enum MemberStatus: Codable {
            /// не является участником
            case not_member
            /// является участником
            case member
            /// не уверен, что посетит мероприятие
            case not_sure
            /// отклонил приглашение
            case declined_invitation
            /// подал заявку на вступление
            case sent_request
            /// приглашен
            case invited
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .not_member
                case 1:
                    self = .member
                case 2:
                    self = .not_sure
                case 3:
                    self = .declined_invitation
                case 4:
                    self = .sent_request
                case 5:
                    self = .invited
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .not_member:
                    return 0
                case .member:
                    return 1
                case .not_sure:
                    return 2
                case .declined_invitation:
                    return 3
                case .sent_request:
                    return 4
                case .invited:
                    return 5
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Group.MemberStatus(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// место, указанное в информации о сообществе
        public struct Place: Codable {
            /// адрес
            public let address: String?
            /// идентификатор города
            public let city: Int?
            /// идентификатор страны
            public let country: Int?
            /// идентификатор места
            public let id: Int?
            /// географическая широта в градусах (от -90 до 90)
            public let latitude: Double?
            /// географическая долгота в градусах (от -180 до 180)
            public let longitude: Double?
            /// название места
            public let title: String?
            /// тип места
            public let type: String?
        }
        /// тип сообщества
        public enum Typе: String, Codable {
            /// мероприятие
            case event
            /// группа
            case group
            /// публичная страница
            case page
        }
        /// строка состояния публичной страницы. У групп возвращается строковое значение, открыта ли группа или нет, а у событий дата начала
        public let activity: String?
        /// уровень полномочий текущего пользователя
        public let admin_level: Object.Group.AdminLevel?
        /// возрастное ограничение
        public let age_limits: Object.Group.AgeLimits?
        /// информация о занесении в черный список сообщества
        public let ban_info: Object.Group.BanInfo?
        /// информация о том, может ли текущий пользователь создать новое обсуждение в группе
        public let can_create_topic: Object.Boolean?
        /// информация о том, может ли текущий пользователь написать сообщение сообществу
        public let can_message: Object.Boolean?
        /// информация о том, может ли текущий пользователь оставлять записи на стене сообщества
        public let can_post: Object.Boolean?
        /// информация о том, разрешено ли видеть чужие записи на стене группы
        public let can_see_all_posts: Object.Boolean?
        /// информация о том, может ли текущий пользователь загружать документы в группу
        public let can_upload_doc: Object.Boolean?
        /// информация о том, может ли текущий пользователь загружать видеозаписи в группу
        public let can_upload_video: Object.Boolean?
        /// город, указанный в информации о сообществе
        public let city: Object.City?
        /// информация из блока контактов публичной страницы
        public let contacts: [Object.Group.Contact]?
        /// объект, содержащий счётчики сообщества
        public let counters: Object.Group.Counters?
        /// страна, указанная в информации о сообществе
        public let country: Object.Country?
        /// обложка сообщества
        public let cover: Object.Group.Cover?
        /// возвращается в случае, если сообщество удалено или заблокировано
        public let deactivated: Object.Group.Deactivated?
        /// текст описания сообщества
        public let description: String?
        /// время в формате unixtime
        public let finish_date: String?
        /// идентификатор закрепленной записи
        public let fixed_post: Int?
        /// информация о том, установлена ли у сообщества главная фотография
        public let has_photo: Object.Boolean?
        /// идентификатор сообщества.
        public let id: Int
        /// идентификатор пользователя, который отправил приглашение в сообщество
        public let invited_by: Int?
        /// информация о том, является ли текущий пользователь руководителем
        public let is_admin: Object.Boolean?
        /// является ли сообщество закрытым
        public let is_closed: Object.Group.IsClosed?
        /// информация о том, находится ли сообщество в закладках у текущего пользователя
        public let is_favorite: Object.Boolean?
        /// информация о том, скрыто ли сообщество из ленты новостей текущего пользователя
        public let is_hidden_from_feed: Object.Boolean?
        /// информация о том, является ли текущий пользователь участником
        public let is_member: Object.Boolean?
        /// информация о том, заблокированы ли сообщения от этого сообщества (для текущего пользователя)
        public let is_messages_blocked: Object.Boolean?
        /// информация из блока ссылок сообщества
        public let links: [Object.Group.Link]?
        /// идентификатор основного фотоальбома
        public let main_album_id: Int?
        /// информация о главной секции
        public let main_section: Object.Group.MainSection?
        /// информация о магазине
        public let market: Object.Group.Market?
        /// статус участника текущего пользователя
        public let member_status: Object.Group.MemberStatus?
        /// количество участников
        public let members_count: Int?
        /// название сообщества
        public let name: String
        /// url главной фотографии с размером 100х100px
        public let photo_100: String?
        /// url главной фотографии в максимальном размере
        public let photo_200: String?
        /// url главной фотографии с размером 50x50px
        public let photo_50: String?
        /// место, указанное в информации о сообществе
        public let place: Object.Group.Place?
        /// текст описания для поля start_date
        public let public_date_label: String?
        /// короткий адрес
        public let screen_name: String?
        /// адрес сайта из поля «веб-сайт» в описании сообщества
        public let site: String?
        /// для встреч время в формате unixtime / для публичных страниц дата основания в формате YYYYMMDD
        public let start_date: String?
        /// status
        public let status: String?
        /// информация о том, есть ли у сообщества «огонёк»
        public let trending: Object.Boolean?
        /// тип сообщества
        public let type: Object.Group.Typе?
        /// информация о том, верифицировано ли сообщество
        public let verified: Object.Boolean?
        /// название главной вики-страницы
        public let wiki_page: String?
    }
    
}

<file_sep>import Foundation

public extension Object {
    /// объект, описывающий альбом с фотографиями
    public struct Album: Codable {
        /// дата создания альбома в формате Unixtime
        public let created: Int?
        /// описание альбома
        public let description: String?
        /// идентификатор альбома
        public let id: String?
        /// идентификатор владельца альбома
        public let owner_id: Int?
        /// количество фотографий в альбоме
        public let size: Int?
        /// обложка альбома, объект photo
        public let thumb: Object.Photo?
        /// название альбома
        public let title: String?
        /// дата последнего обновления альбома в формате Unixtime
        public let updated: Int?
    }
}
<file_sep>import Foundation

public extension Object {
    /// пользователь
    public struct Photo: Codable {
        /// формат описания размеров фотографии
        public struct Size: Codable {
            /// обозначение размера и пропорций копии
            public enum Typе: String, Codable {
                /// k
                case k
                /// l
                case l
                /// пропорциональная копия изображения с максимальной стороной 130px
                case m
                /// если соотношение "ширина/высота" исходного изображения меньше или равно 3:2, то пропорциональная копия с максимальной стороной 130px. Если соотношение "ширина/высота" больше 3:2, то копия обрезанного слева изображения с максимальной стороной 130px и соотношением сторон 3:2
                case o
                ///  если соотношение "ширина/высота" исходного изображения меньше или равно 3:2, то пропорциональная копия с максимальной стороной 200px. Если соотношение "ширина/высота" больше 3:2, то копия обрезанного слева и справа изображения с максимальной стороной 200px и соотношением сторон 3:2
                case p
                /// если соотношение "ширина/высота" исходного изображения меньше или равно 3:2, то пропорциональная копия с максимальной стороной 320px. Если соотношение "ширина/высота" больше 3:2, то копия обрезанного слева и справа изображения с максимальной стороной 320px и соотношением сторон 3:2
                case q
                /// если соотношение "ширина/высота" исходного изображения меньше или равно 3:2, то пропорциональная копия с максимальной стороной 510px. Если соотношение "ширина/высота" больше 3:2, то копия обрезанного слева и справа изображения с максимальной стороной 510px и соотношением сторон 3:2
                case r
                /// пропорциональная копия изображения с максимальной стороной 75px
                case s
                /// пропорциональная копия изображения с максимальным размером 2560x2048px
                case w
                /// пропорциональная копия изображения с максимальной стороной 604px
                case x
                /// пропорциональная копия изображения с максимальной стороной 807px
                case y
                /// пропорциональная копия изображения с максимальным размером 1080x1024
                case z
            }
            /// высота копии в пикселах
            public let height: UInt?
            /// URL копии изображения
            public let src: String
            /// обозначение размера и пропорций копии
            public let type: Object.Photo.Size.Typе
            /// ширина копии в пикселах
            public let width: UInt?
        }
        /// ключ доступа к объекту
        public let access_key: String?
        /// идентификатор альбома, в котором находится фотография
        public let album_id: Int?
        /// дата добавления в формате Unixtime
        public let date: Int?
        ///
        public let has_filter: Object.Positive?
        /// высота оригинала фотографии в пикселах
        public let height: UInt?
        /// идентификатор фотографии
        public let id: Int?
        ///
        public let is_mail: Object.Positive?
        ///
        public let is_room: Object.Positive?
        /// lat
        public let lat: Double?
        /// long
        public let long: Double?
        /// идентификатор владельца фотографии
        public let owner_id: Int?
        /// URL копии фотографии с максимальным размером 1280x1024px
        public let photo_1280: String?
        /// URL копии фотографии с максимальным размером 130x130px
        public let photo_130: String?
        /// URL копии фотографии с максимальным размером 2560x2048px
        public let photo_2560: String?
        /// URL копии фотографии с максимальным размером 604x604px
        public let photo_604: String?
        /// URL копии фотографии с максимальным размером 75x75px
        public let photo_75: String?
        /// URL копии фотографии с максимальным размером 807x807px
        public let photo_807: String?
        /// идентификатор записи, в которую была загружена фотография
        public let post_id: Int?
        /// массив с копиями изображения в разных размерах
        public let sizes: [Object.Photo.Size]?
        ///
        public let src_big: String?
        ///
        public let src_small: String?
        /// текст описания фотографии
        public let text: String?
        /// идентификатор пользователя
        public let user_id: Int?
        /// ширина оригинала фотографии в пикселах
        public let width: UInt?
    }
}

<file_sep>import Foundation

public extension Object {
    /// объект, описывающий товар
    public struct MarketItem: Codable {
        /// статус доступности товара
        public enum Availability: Codable {
            /// товар доступен
            case available
            /// товар удален
            case deleted
            /// товар недоступен
            case unavailable
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .available
                case 1:
                    self = .deleted
                case 2:
                    self = .unavailable
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .available:
                    return 0
                case .deleted:
                    return 1
                case .unavailable:
                    return 2
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.MarketItem.Availability(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// категория товара
        public struct Category: Codable {
            /// секция
            public struct Section: Codable {
                /// идентификатор секции
                public let id: Int?
                /// название секции
                public let name: String?
            }
            /// идентификатор категории
            public let id: Int?
            /// название категории
            public let name: String?
            /// секция
            public let section: Object.MarketItem.Category.Section?
        }
        /// информация об отметках «Мне нравится»
        public struct Likes: Codable {
            /// число отметок «Мне нравится»
            let count: Int?
            /// есть ли отметка «Мне нравится» от текущего пользователя
            let user_likes: Object.Boolean?
        }
        /// объект, описывающий цену
        public struct Price: Codable {
            /// объект, описывающий информацию о валюте
            public struct Currency: Codable {
                /// идентификатор валюты
                public let id: Int?
                /// буквенное обозначение валюты
                public let name: String?
            }
            /// цена товара в сотых долях единицы валюты
            public let amount: String?
            /// объект currency
            public let currency: Object.MarketItem.Price.Currency?
            /// строка с локализованной ценой и валютой
            public let text: String?
        }
        /// статус доступности товара
        public let availability: Object.MarketItem.Availability?
        /// возможность комментировать товар для текущего пользователя
        public let can_comment: Object.Boolean?
        /// возможность сделать репост товара для текущего пользователя
        public let can_repost: Object.Boolean?
        /// категория товара
        public let category: Object.MarketItem.Category?
        /// creation date in Unixtime
        public let date: Int?
        /// текст описания товара
        public let description: String?
        /// идентификатор товара
        public let id: Int?
        /// информация об отметках «Мне нравится»
        public let likes: Object.MarketItem.Likes?
        /// идентификатор владельца товара
        public let owner_id: Int?
        /// изображения товара
        public let photos: [Object.Photo]?
        /// цена
        public let price: Object.MarketItem.Price?
        /// URL of the item photo
        public let thumb_photo: String?
        /// название товара
        public let title: String?
    }
}

<file_sep>import Foundation

public extension Object {
    /// объект, описывающий кнопку
    public struct Button: Codable {
        /// действие для кнопки
        public struct Action: Codable {
            /// тип действия
            public enum Typе: String, Codable {
                /// вступить в группу и открыть адрес из поля url
                case join_group_and_open_url
                /// открыть адрес из поля url
                case open_url
            }
            /// идентификатор группы
            public let group_id: Int?
            ///
            public let target: Object.Target?
            /// тип действия
            public let type: Object.Button.Action.Typе?
            /// URL для перехода
            public let url: String?
        }
        /// действие для кнопки
        public let action: Object.Button.Action?
        /// название кнопки
        public let title: String?
    }
}
<file_sep>import Foundation
/// специальный ключ доступа для идентификации в API
public typealias Token = String
<file_sep>//import Foundation
//
//public extension Method.Utils {
//    /// Возвращает информацию о том, является ли внешняя ссылка заблокированной на сайте ВКонтакте
//    public struct CheckLink {
//        /// ответ
//        public typealias Response = Object.CheckedLink
//        /// внешняя ссылка, которую необходимо проверить
//        public let url: String
//        /// пользовательские данные
//        public let user: App.User
//
//        public init(url: String, user: App.User) {
//            self.url = url
//            self.user = user
//        }
//    }
//}
//
//extension Method.Utils.CheckLink: ApiType {
//
//    public var method_name: String {
//        return "utils.checkLink"
//    }
//
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        dictionary["access_token"] = user.token
//        dictionary["url"] = url
//        return dictionary
//    }
//}
//
//extension Method.Utils.CheckLink: StrategyType {
//
//    public var api: AnyApi<Method.Utils.CheckLink.Response> {
//        return AnyApi(api: self)
//    }
//}
<file_sep>//import Foundation
//
//public extension Method.Utils {
//    /// Позволяет получить URL, сокращенный с помощью vk.cc.
//    public struct DeleteFromLastShortened {
//        /// ответ
//        public typealias Response = Object.Positive
//        /// содержательная часть (символы после "vk.cc")
//        public let key: String
//        /// пользовательские данные
//        public let user: App.User
//        
//        public init(key: String, user: App.User) {
//            self.key = key
//            self.user = user
//        }
//    }
//}
//
//extension Method.Utils.DeleteFromLastShortened: ApiType {
//    
//    public var method_name: String {
//        return "utils.deleteFromLastShortened"
//    }
//    
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        dictionary["access_token"] = user.token
//        dictionary["key"] = key
//        return dictionary
//    }
//}
//
//extension Method.Utils.DeleteFromLastShortened: StrategyType {
//    
//    public var api: AnyApi<Method.Utils.DeleteFromLastShortened.Response> {
//        return AnyApi(api: self)
//    }
//}
//
<file_sep>import Foundation

extension UnkeyedDecodingContainer {
    
    mutating func decode<T>() throws -> T where T: Decodable {
        return try decode(T.self)
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий контент приложения
    public struct App: Codable {
        /// идентификатор приложения
        public let id: Int?
        /// название приложения
        public let name: String?
        /// URL изображения для предпросмотра
        public let photo_130: String?
        /// URL полноразмерного изображения
        public let photo_604: String?
    }
}
<file_sep>import RxCocoa
import RxSwift

extension Observable {
    
    func delayCompletion(_ dueTime: RxTimeInterval, scheduler: SchedulerType) -> Observable {
        let observableElement = self
            .observeOn(scheduler)
            .share(replay: 1, scope: .whileConnected)
        let observableCompleted = Observable<Int>
            .timer(0, period: dueTime, scheduler: scheduler)
            .map({ $0 > 0 })
            .share(replay: 1, scope: .whileConnected)
        return Observable<(element: E, completed: Bool)>
            .combineLatest(observableElement, observableCompleted){(element: $0, completed: $1)}
            .filter({ $0.completed })
            .map({ $0.element })
            .take(1)
            .share(replay: 1, scope: .whileConnected)
    }
    
    func flatMapLatest<T>(observableCancel: Observable<T>, observableFactory: @escaping (E) throws -> Observable<T>) -> Observable<T> {
        return self
            .flatMapLatest({ element -> Observable<T> in
                return Observable<Observable<T>>
                    .of(observableCancel, try observableFactory(element))
                    .merge()
                    .take(1)
            })
            .share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
    }
    
    func observableTracked(activityRelay: ActivityRelay?) -> Observable {
        return activityRelay?.trackActivity(self) ?? self
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий стикер
    public struct Sticker: Codable {
        /// высота в px
        public let height: Int?
        /// идентификатор стикера
        public let id: Int?
        /// URL изображения с высотой 128 px
        public let photo_128: String?
        /// URL изображения с высотой 256 px
        public let photo_256: String?
        /// URL изображения с высотой 352 px
        public let photo_352: String?
        /// URL изображения с высотой 64 px
        public let photo_64: String?
        /// идентификатор набора
        public let product_id: Int?
        /// ширина в px
        public let width: Int?
    }
}
<file_sep># git tag 3.0.0
# git push origin 3.0.0
# pod lib lint VK.podspec --no-clean
# pod spec lint VK.podspec --allow-warnings
# pod trunk push VK.podspec
# pod lib lint VK+Extended.podspec --no-clean
# pod spec lint VK+Extended.podspec --allow-warnings
# pod trunk push VK+Extended.podspec

Pod::Spec.new do |s|

    s.name                      = 'VK'
    s.version                   = '3.0.0'
    s.summary                   = 'vk.com, api, swift'
    s.description               = 'vk.com, api, swift, decodable, moya, rxswift'
    s.homepage                  = 'https://github.com/iwheelbuy/VK'
    s.license                   = { :type => 'MIT', :file => 'LICENSE' }
    s.author                    = { 'iWheelBuy' => '<EMAIL>' }
    s.source                    = { :git => 'https://github.com/iwheelbuy/VK.git', :tag => s.version.to_s }
    s.ios.deployment_target     = '10.0'
    s.pod_target_xcconfig       = { 'SWIFT_VERSION' => '4.1' }
    s.default_subspec           = 'Base'
    
    s.subspec 'Base' do |ss|
        ss.source_files = 'VK/Core/**/*.swift', 'VK/Extra/**/*.swift', 'VK/Method/**/*.swift', 'VK/Object/**/*.swift'
        ss.dependency 'Moya/RxSwift'
        ss.dependency 'RxCocoa'
    end
end
<file_sep>//import Foundation
//
//public extension Method.Utils {
//    /// Позволяет получить URL, сокращенный с помощью vk.cc.
//    public struct GetShortLink {
//        /// ответ
//        public typealias Response = Object.ShortenedLink
//        /// статистика ссылки приватная
//        public let `private`: Bool
//        /// сдвиг для получения определенного подмножества ссылок
//        public let url: String
//        /// пользовательские данные
//        public let user: App.User
//        
//        public init(`private`: Bool = false, url: String, user: App.User) {
//            self.`private` = `private`
//            self.url = url
//            self.user = user
//        }
//    }
//}
//
//extension Method.Utils.GetShortLink: ApiType {
//    
//    public var method_name: String {
//        return "utils.getShortLink"
//    }
//    
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        dictionary["access_token"] = user.token
//        dictionary["private"] = `private` ? "1" : "0"
//        dictionary["url"] = url
//        return dictionary
//    }
//}
//
//extension Method.Utils.GetShortLink: StrategyType {
//    
//    public var api: AnyApi<Method.Utils.GetShortLink.Response> {
//        return AnyApi(api: self)
//    }
//}
<file_sep>import Foundation

public extension Object {
    /// изображение обложки
    public struct Image: Codable {
        /// высота копии
        public let height: Int?
        /// URL копии
        public let url: String?
        /// ширина копии
        public let width: Int?
    }
}
<file_sep>import Foundation

public extension Object {
    /// перечисление, обозначающиее положительный или отрицательный результат
    public enum Boolean: Int, Codable {
        /// отрицательный результат
        case negative = 0
        /// положительный результат
        case positive = 1
    }
}
<file_sep>import Foundation

public extension Method.Utils {
    /// Возвращает текущее время на сервере ВКонтакте в unixtime.
    public struct GetServerTime: Strategy {
        /// ключ доступа
        public let token: Token
        
        public init(token: Token) {
            self.token = token
        }
        
        public var method: String {
            return "utils.getServerTime"
        }
        
        public var parameters: [String : Any] {
            var dictionary = [String : Any]()
            dictionary["access_token"] = token
            return dictionary
        }
        
        public var transform: (Object.Response<Int>) -> Int {
            return { $0.response }
        }
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий заметку
    public struct Note: Codable {
        /// количество комментариев
        public let comments: Int?
        /// дата создания заметки в формате Unixtime
        public let date: Int?
        /// идентификатор заметки
        public let id: Int?
        /// идентификатор владельца заметки
        public let owner_id: Int?
        /// количество прочитанных комментариев
        public let read_comments: Int?
        /// текст заметки
        public let text: String?
        /// заголовок заметки
        public let title: String?
        /// URL страницы для отображения заметки
        public let view_url: String?
    }
}

<file_sep>import Moya
import RxSwift

public protocol Service: class {
    ///
    func activity() -> Observable<Bool>
    ///
    func request<C, S, V>(cancel: Observable<C>, delay: TimeInterval, lang: String, logs: Logs, queue: DispatchQueue, strategy: S, timeout: TimeInterval, track: Bool, v: String) -> Observable<Output<V>> where S: Strategy, S.Value == V
}

public func getService() -> Service {
    return _Service()
}

// MARK: - Target: Moya.TargetType

private struct Target: Moya.TargetType {
    
    let baseURL: URL
    let headers: [String: String]? = nil
    let method: Moya.Method
    let path: String
    let sampleData: Data
    let task: Moya.Task
    
    init<S>(_ lang: String, _ strategy: S, _ v: String) throws where S: Strategy {
        switch URL(string: "https://api.vk.com/method/") {
        case .some(let baseURL):
            self.baseURL = baseURL
        default:
            assertionFailure()
            throw Fault.baseUrl
        }
        self.method = Moya.Method.get
        self.path = strategy.method
        self.sampleData = Data()
        var parameters = strategy.parameters
        parameters["lang"] = lang
        parameters["v"] = v
        self.task = Moya.Task.requestParameters(parameters: parameters, encoding: URLEncoding())
    }
}

// MARK: - Provider<T>: MoyaProvider<T>

private class Provider<T>: MoyaProvider<T>, Disposable where T: Moya.TargetType {
    
    init(logs: Bool, queue: DispatchQueue) {
        let plugins = logs ? [NetworkLoggerPlugin(verbose: true)] : []
        super.init(callbackQueue: queue, plugins: plugins)
    }
    
    func dispose() {
        //
    }
}

// MARK: - Service

private class _Service {
    
    lazy var activityRelay = ActivityRelay()
    
    func observableCancel<C, T>(_ observableCancel: Observable<C>, _ observableTimeout: Observable<Output<T>>) -> Observable<Output<T>> {
        return Observable
            .of(observableTimeout, observableCancel.map({ _ in Output<T>.fault(.cancel) }))
            .merge()
            .take(1)
            .share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
    }
    
    func observableFactory<S, T>(_ lang: String, _ logs: Bool, _ queue: DispatchQueue, _ strategy: S, _ v: String) -> () throws -> Observable<Output<T>> where S: Strategy, S.Value == T {
        return { () -> Observable<Output<T>> in
            assert(Thread.isMainThread == false)
            let target = try Target(lang, strategy, v)
            return Observable
                .using({ Provider<Target>(logs: logs, queue: queue) }, observableFactory: { (provider) -> Observable<Output<T>> in
                    assert(Thread.isMainThread == false)
                    return provider.rx
                        .request(target, callbackQueue: queue)
                        .asObservable()
                        .map({ Output.with(response: $0, strategy: strategy) })
                        .catchError({ (error) -> Observable<Output<T>> in
                            assert(Thread.isMainThread == false)
                            let fault = Fault(error: error)
                            return Observable
                                .just(Output.fault(fault), scheduler: ConcurrentDispatchQueueScheduler(queue: queue))
                        })
                })
        }
    }
    
    func observableTimeout<T>(_ timeout: TimeInterval, _ queue: DispatchQueue) -> Observable<Output<T>> {
        return Observable<Int>
            .timer(timeout, period: timeout, scheduler: ConcurrentDispatchQueueScheduler(queue: queue))
            .take(1)
            .map({ _ in Output<T>.fault(Fault.timeout) })
            .share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
    }
}

// MARK: - _Service: NetworkService

extension _Service: Service {
    
    public func activity() -> Observable<Bool> {
        return activityRelay
            .asObservable()
    }
    
    public func request<C, S, V>(cancel: Observable<C>, delay: TimeInterval, lang: String, logs: Logs, queue: DispatchQueue, strategy: S, timeout: TimeInterval, track: Bool, v: String) -> Observable<Output<V>> where S: Strategy, S.Value == V {
        let observableTimeout: Observable<Output<V>> = self.observableTimeout(timeout, queue)
        let observableCancel: Observable<Output<V>> = self.observableCancel(cancel, observableTimeout)
        let observableFactory: () throws -> Observable<Output<V>> = self.observableFactory(lang, logs.contains(.request), queue, strategy, v)
        let observableRequest: Observable<Output<V>> = Observable
            .just((), scheduler: ConcurrentDispatchQueueScheduler(queue: queue))
            .flatMapLatest(observableCancel: observableCancel, observableFactory: observableFactory)
        let observableDelayedTracked: Observable<Output<V>> = {
            switch (delay > 0, track) {
            case (true, true):
                return observableRequest
                    .delayCompletion(delay, scheduler: ConcurrentDispatchQueueScheduler(queue: queue))
                    .observableTracked(activityRelay: activityRelay)
            case (true, false):
                return observableRequest
                    .delayCompletion(delay, scheduler: ConcurrentDispatchQueueScheduler(queue: queue))
            case (false, true):
                return observableRequest
                    .observableTracked(activityRelay: activityRelay)
            case (false, false):
                return observableRequest
            }
        }()
        return observableDelayedTracked
            .share(replay: 1, scope: SubjectLifetimeScope.whileConnected)
    }
}
<file_sep>//import Foundation
//
//public extension Method.Utils {
//    /// тип объекта (пользователь, сообщество, приложение) и его идентификатор по короткому имени screen_name
//    public struct ResolveScreenName {
//        /// ответ
//        public typealias Response = Object.ResolvedScreenName?
//        /// короткое имя пользователя, группы или приложения
//        public let screen_name: String
//        /// пользовательские данные
//        public let user: App.User?
//        
//        public init(screen_name: String, user: App.User? = nil) {
//            self.screen_name = screen_name
//            self.user = user
//        }
//    }
//}
//
//extension Method.Utils.ResolveScreenName: ApiType {
//    
//    public var method_name: String {
//        return "utils.resolveScreenName"
//    }
//    
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        dictionary["access_token"] = user?.token
//        dictionary["screen_name"] = screen_name
//        return dictionary
//    }
//}
//
//extension Method.Utils.ResolveScreenName: StrategyType {
//    
//    public var api: AnyApi<Method.Utils.ResolveScreenName.Response> {
//        return AnyApi(api: self)
//    }
//}
<file_sep>import Foundation

public extension Object {
    /// запись на стене пользователя или сообщества
    public struct Wall: Codable {
        /// информация о комментариях к записи
        public struct Comments: Codable {
            /// количество комментариев
            let count: Int?
            /// информация о том, может ли текущий пользователь комментировать запись
            let can_post: Object.Boolean?
            /// информация о том, могут ли сообщества комментировать запись
            let groups_can_post: Bool?
        }
        /// информация о местоположении
        public struct Geo: Codable {
            /// тип места
            public enum Typе: Codable {
                /// место
                case place
                /// точка
                case point
                /// неизвестное значение
                case exception(String)
                
                init(rawValue: String) {
                    switch rawValue {
                    case "place":
                        self = .place
                    case "point":
                        self = .point
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: String {
                    switch self {
                    case .place:
                        return "place"
                    case .point:
                        return "point"
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: String = try container.decode()
                    self = Object.Wall.Geo.Typе(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            ///
            public enum Place {
                /// описание места
                public struct Place: Codable {
                    /// адрес
                    public let address: String?
                    /// количество чекинов
                    public let checkins: Int?
                    /// идентификатор города
                    public let city: Int?
                    /// идентификатор страны
                    public let country: Int?
                    /// дата создания (если назначено)
                    public let created: Int?
                    /// идентификатор сообщества
                    public let group_id: Int?
                    /// URL миниатюры главной фотографии сообщества
                    public let group_photo: String?
                    /// URL изображения-иконки
                    public let icon: String?
                    /// идентификатор места (если назначено)
                    public let id: Int?
                    /// географическая широта
                    public let latitude: Double?
                    /// географическая долгота
                    public let longitude: Double?
                    /// название места (если назначено)
                    public let title: String?
                    /// тип чекина
                    public let type: Int?
                    /// время последнего чекина в Unixtime
                    public let updated: Int?
                }
                /// описание точки
                public struct Point: Codable {
                    /// название города
                    public let city: String?
                    /// название страны
                    public let country: String?
                    /// дата создания (если назначено)
                    public let created: Int?
                    /// URL изображения-иконки
                    public let icon: String?
                    /// идентификатор места (если назначено)
                    public let id: Int?
                    /// географическая широта
                    public let latitude: Double?
                    /// географическая долгота
                    public let longitude: Double?
                    /// название места (если назначено)
                    public let title: String?
                }
                /// описание места
                case place(Object.Wall.Geo.Place.Place?)
                /// описание точки
                case point(Object.Wall.Geo.Place.Point?)
            }
            
            private enum Key: String, CodingKey {
                case coordinates
                case place
                case showmap
                case type
            }
            
            /// координаты места
            public let coordinates: String?
            /// описание места
            public let place: Object.Wall.Geo.Place
            /// showmap
            public let showmap: Object.Positive?
            /// тип места
            public let type: Object.Wall.Geo.Typе
            
            public init(from decoder: Decoder) throws {
                let container = try Key.container(decoder: decoder)
                coordinates = try container.decode(key: Key.coordinates)
                if container.contains(Key.showmap) {
                    showmap = try container.decode(key: Key.showmap)
                } else {
                    showmap = nil
                }
                type = try container.decode(key: Key.type)
                switch type {
                case .place:
                    if container.contains(Key.place) {
                        let place: Object.Wall.Geo.Place.Place? = try container.decode(key: Key.place)
                        self.place = .place(place)
                    } else {
                        self.place = .place(nil)
                    }
                case .point:
                    if container.contains(Key.place) {
                        let point: Object.Wall.Geo.Place.Point? = try container.decode(key: Key.place)
                        self.place = .point(point)
                    } else {
                        self.place = .point(nil)
                    }
                case .exception:
                    let place: Object.Wall.Geo.Place.Place = try container.decode(key: Key.place)
                    self.place = .place(place)
                }
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = Key.container(encoder: encoder)
                try container.encode(coordinates, forKey: Key.coordinates)
                switch self.showmap {
                case .some(let showmap):
                    try container.encode(showmap, forKey: Key.showmap)
                default:
                    break
                }
                try container.encode(type, forKey: Key.type)
                switch self.place {
                case .place(let place):
                    try container.encode(place, forKey: Key.place)
                case .point(let point):
                    if case .some(let point) = point {
                        try container.encode(point, forKey: Key.place)
                    }
                }
            }
        }
        /// информация о лайках к записи
        public struct Likes: Codable {
            /// число пользователей, которым понравилась запись
            let count: Int?
            /// информация о том, может ли текущий пользователь поставить отметку «Мне нравится»
            let can_like: Object.Boolean?
            /// информация о том, может ли текущий пользователь сделать репост записи
            let can_publish: Object.Boolean?
            /// наличие отметки «Мне нравится» от текущего пользователя
            let user_likes: Object.Boolean?
        }
        /// тип записи
        public enum PostType: String, Codable {
            case copy
            case note
            case photo
            case post
            case postpone
            case reply
            case suggest
            case video
        }
        /// способ размещения записи на стене
        public struct PostSource: Codable {
            /// тип действия (только для type = vk или widget)
            public enum Data: String, Codable {
                /// донат
                case donation
                /// изменение статуса под именем пользователя (для type = vk)
                case profile_activity
                /// изменение профильной фотографии пользователя (для type = vk)
                case profile_photo
                /// виджет комментариев (для type = widget)
                case comments
                /// виджет «Мне нравится» (для type = widget)
                case like
                /// виджет опросов (для type = widget)
                case poll
                /// добавление в wishlist
                case wishlist_add
                /// покупка из wishlist
                case wishlist_buy
            }
            /// link
            public struct Link: Codable {
                /// description
                public let description: String?
                /// title
                public let title: String?
                /// url
                public let url: String?
            }
            /// название платформы, если оно доступно
            public enum Platform: String, Codable {
                /// admin_app
                case admin_app
                /// android
                case android
                /// chronicle
                case chronicle
                /// instagram
                case instagram
                /// ipad
                case ipad
                /// iphone
                case iphone
                /// windows
                case windows
                /// windows phone
                case wphone
            }
            /// тип источника
            public enum Typе: String, Codable {
                /// запись создана приложением через API
                case api
                /// мобильная версия m.vk.com
                case mvk
                /// запись создана посредством импорта RSS-ленты со стороннего сайта
                case rss
                /// запись создана посредством отправки SMS-сообщения на специальный номер
                case sms
                /// запись создана через основной интерфейс сайта
                case vk
                /// запись создана через виджет на стороннем сайте
                case widget
            }
            /// тип действия (только для type = vk или widget)
            let data: Object.Wall.PostSource.Data?
            /// link
            let link: Object.Wall.PostSource.Link?
            /// название платформы, если оно доступно
            let platform: Object.Wall.PostSource.Platform?
            /// тип источника
            let type: Object.Wall.PostSource.Typе
            /// URL ресурса, с которого была опубликована запись
            let url: String?
        }
        /// информация о репостах записи («Рассказать друзьям»)
        public struct Reposts: Codable {
            /// число пользователей, скопировавших запись
            let count: Int?
            ///  наличие репоста от текущего пользователя
            let user_reposted: Object.Boolean?
        }
        /// информация о просмотрах записи
        public struct Views: Codable {
            /// число просмотров записи
            let count: Int?
        }
        /// медиавложения записи (фотографии, ссылки и т.п.)
        public let attachments: [Object.Attachment]?
        /// информация о том, может ли текущий пользователь удалить запись
        public let can_delete: Object.Boolean?
        /// информация о том, может ли текущий пользователь редактировать запись
        public let can_edit: Object.Boolean?
        /// информация о том, может ли текущий пользователь закрепить запись
        public let can_pin: Object.Boolean?
        /// информация о комментариях к записи
        public let comments: Object.Wall.Comments?
        /// массив, содержащий историю репостов для записи. Возвращается только в том случае, если запись является репостом. Каждый из объектов массива, в свою очередь, является объектом-записью стандартного формата
        public let copy_history: [Object.Wall]?
        /// идентификатор администратора, который опубликовал запись
        public let created_by: Int?
        /// время публикации записи в формате unixtime
        public let date: TimeInterval
        /// final_post
        public let final_post: Object.Positive?
        /// запись была создана с опцией «Только для друзей»
        public let friends_only: Object.Positive?
        /// идентификатор автора записи (от чьего имени опубликована запись)
        public let from_id: Int
        /// информация о местоположении
        public let geo: Object.Wall.Geo?
        /// идентификатор записи
        public let id: Int?
        /// информация о том, что запись закреплена
        public let is_pinned: Object.Positive?
        /// информация о лайках к записи
        public let likes: Object.Wall.Likes?
        /// информация о том, содержит ли запись отметку "реклама"
        public let marked_as_ads: Object.Boolean?
        /// информация о способе размещения записи
        public let post_source: Object.Wall.PostSource
        /// тип записи
        public let post_type: Object.Wall.PostType?
        /// идентификатор владельца записи, в ответ на которую была оставлена текущая
        public let reply_owner_id: Int?
        /// идентификатор записи, в ответ на которую была оставлена текущая
        public let reply_post_id: Int?
        /// информация о репостах записи («Рассказать друзьям»)
        public let reposts: Object.Wall.Reposts?
        /// идентификатор автора, если запись была опубликована от имени сообщества и подписана пользователем
        public let signer_id: Int?
        /// идентификатор владельца стены, на которой размещена запись
        public let owner_id: Int
        /// текст записи
        public let text: String
        /// информация о просмотрах записи
        public let views: Object.Wall.Views?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий вики-страницу
    public struct Page: Codable {
        /// информация о том, кто может просматривать/редактировать вики-страницу
        public enum Who: Codable {
            /// только руководители сообщества
            case managers
            /// только участники сообщества
            case members
            /// просматривать страницу могут все
            case all
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .managers
                case 1:
                    self = .members
                case 2:
                    self = .all
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .managers:
                    return 0
                case .members:
                    return 1
                case .all:
                    return 2
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Page.Who(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// дата создания вики-страницы в формате Unixtime
        public let created: Int?
        /// идентификатор создателя вики-страницы
        public let creator_id: Int?
        /// текущий пользователь может редактировать текст вики-страницы
        public let current_user_can_edit: Object.Boolean?
        /// текущий пользователь может изменять права доступа на вики-страницу
        public let current_user_can_edit_access: Object.Boolean?
        /// дата последнего изменения вики-страницы в формате Unixtime
        public let edited: Int?
        /// идентификатор пользователя, который редактировал вики-страницу последним
        public let editor_id: Int?
        /// идентификатор сообщества
        public let group_id: Int?
        /// текст страницы в html-формате, если был запрошен
        public let html: String?
        /// идентификатор вики-страницы
        public let id: Int?
        /// заголовок родительской страницы для навигации, если есть
        public let parent: String?
        ///  заголовок второй родительской страницы для навигации, если есть
        public let parent2: String?
        /// текст страницы в вики-формате, если был запрошен
        public let source: String?
        /// название вики-страницы
        public let title: String?
        /// адрес страницы для отображения вики-страницы
        public let view_url: String?
        /// количество просмотров вики-страницы
        public let views: Int?
        /// указывает, кто может редактировать вики-страницу
        public let who_can_edit: Object.Page.Who?
        /// информация о том, кто может просматривать вики-страницу
        public let who_can_view: Object.Page.Who?
    }
}

<file_sep>import Foundation

/// методы для работы с данными ВКонтакте
public struct Method {
    /// служебные методы
    public struct Utils {}
    /// методы для работы с записями на стене.
    public struct Wall {}
}
<file_sep>import Foundation

extension KeyedDecodingContainer {
    
    func decode<T>(key: K) throws -> T where T: Decodable {
        return try decode(T.self, forKey: key)
    }
}
<file_sep>import Foundation

public extension Object {
    /// информацию о том, является ли внешняя ссылка заблокированной на сайте ВКонтакте
    public struct CheckedLink: Codable {
        /// статус ссылки
        public enum Status: Codable {
            /// ссылка не заблокирована
            case not_banned
            /// ссылка заблокирована
            case banned
            /// ссылка проверяется, необходимо выполнить повторный запрос через несколько секунд
            case processing
            /// неизвестное значение
            case exception(String)
            
            init(rawValue: String) {
                switch rawValue {
                case "not_banned":
                    self = .not_banned
                case "banned":
                    self = .banned
                case "processing":
                    self = .processing
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: String {
                switch self {
                case .not_banned:
                    return "not_banned"
                case .banned:
                    return "banned"
                case .processing:
                    return "processing"
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: String = try container.decode()
                self = Object.CheckedLink.Status(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// исходная ссылка (url) либо полная ссылка (если в url была передана сокращенная ссылка)
        public let link: String?
        /// статус ссылки
        public let status: Object.CheckedLink.Status?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект отвечающий короткому имени screen_name
    public struct ResolvedScreenName: Codable {
        /// тип объекта
        public enum Typе: Codable {
            /// пользователь
            case user
            /// сообщество
            case group
            /// приложение
            case application
            /// неизвестное значение
            case exception(String)
            
            init(rawValue: String) {
                switch rawValue {
                case "user":
                    self = .user
                case "group":
                    self = .group
                case "application":
                    self = .application
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: String {
                switch self {
                case .user:
                    return "user"
                case .group:
                    return "group"
                case .application:
                    return "application"
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: String = try container.decode()
                self = Object.ResolvedScreenName.Typе(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// идентификатор объекта
        public let object_id: Int
        /// тип объекта
        public let type: Object.ResolvedScreenName.Typе
    }
}
<file_sep>import Foundation

extension JSONDecoder {
    
    func decode<T>(data: Data) throws -> T where T: Decodable {
        return try decode(T.self, from: data)
    }
}
<file_sep>//import Foundation
//
//public extension Method.Wall {
//    /// Возвращает список записей со стены пользователя или сообщества
//    public struct Get {
//        /// ответ
//        public struct Response: Codable {
//            /// число результатов
//            public let count: Int
//            /// массив сообществ
//            public let groups: [Object.Group]?
//            /// массив объектов записей на стене
//            public let items: [Object.Wall]
//            /// массив пользователей
//            public let profiles: [Object.Profile]?
//        }
//        /// определяет, какие типы записей на стене необходимо получить
//        public enum Filter: String {
//            /// все записи на стене (owner + others)
//            case all
//            /// записи не от владельца стены
//            case others
//            /// записи владельца стены
//            case owner
//            /// отложенные записи
//            case postponed
//            /// предложенные записи на стене сообщества
//            case suggests
//        }
//        /// идентификатор пользователя или сообщества / короткий адрес пользователя или сообщества
//        public enum Owner {
//            /// короткий адрес пользователя или сообщества
//            case domain(String)
//            /// идентификатор пользователя или сообщества, со стены которого необходимо получить записи (по умолчанию — текущий пользователь)
//            case id(Int?)
//        }
//        ///
//        public enum Sizes {
//            /// включая массив с копиями изображения в разных размерах
//            case array
//            /// исключая массив с копиями изображения в разных размерах
//            case simple
//            var value: String? {
//                switch self {
//                case .array:
//                    return "1"
//                default:
//                    return nil
//                }
//            }
//        }
//        
//        public let filter: Method.Wall.Get.Filter
//        public let count: UInt
//        public let extended: Bool
//        public let offset: UInt
//        public let owner: Method.Wall.Get.Owner
//        public let photoSizes: Method.Wall.Get.Sizes
//        public let user: App.User
//        
//        public init(count: UInt, extended: Bool = false, filter: Method.Wall.Get.Filter = .all, offset: UInt, owner: Method.Wall.Get.Owner = .id(nil), photoSizes: Method.Wall.Get.Sizes = .simple, user: App.User) {
//            self.count = count
//            self.extended = extended
//            self.filter = filter
//            self.offset = offset
//            self.owner = owner
//            self.photoSizes = photoSizes
//            self.user = user
//        }
//    }
//}
//
//extension Method.Wall.Get: ApiType {
//    
//    public var method_name: String {
//        return "wall.get"
//    }
//    
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        if let value = photoSizes.value {
//            dictionary["photo_sizes"] = value
//        }
//        dictionary["access_token"] = user.token
//        dictionary["count"] = "\(count)"
//        dictionary["extended"] = extended ? "1" : "0"
//        dictionary["filter"] = filter.rawValue
//        dictionary["offset"] = "\(offset)"
//        if extended {
//            let fieldsUser = "about, activities, bdate, blacklisted, blacklisted_by_me, books, can_post, can_see_all_posts, can_see_audio, can_send_friend_request, can_write_private_message, career, city, common_count, connections, contacts, counters, country, crop_photo, domain, education, exports, first_name_abl, first_name_acc, first_name_dat, first_name_gen, first_name_ins, first_name_nom, followers_count, friend_status, games, has_mobile, has_photo, home_town, interests, is_favorite, is_friend, is_hidden_from_feed, last_name_abl, last_name_acc, last_name_dat, last_name_gen, last_name_ins, last_name_nom, last_seen, lists, maiden_name, military, movies, music, nickname, occupation, online, personal, photo_50, photo_100, photo_200_orig, photo_200, photo_400_orig, photo_id, photo_max, photo_max_orig, quotes, relatives, relation, schools, screen_name, sex, site, status, timezone, trending, tv, universities, verified, wall_comments"
//            let fieldsGroup = "id, name, screen_name, is_closed, deactivated, is_admin, admin_level, is_member, invited_by, type, photo_50, photo_100, photo_200, activity, age_limits, ban_info, can_create_topic, can_message, can_post, can_see_all_posts, can_upload_doc, can_upload_video, city, contacts, counters, country, cover, description, fixed_post, has_photo, is_favorite, is_hidden_from_feed, is_messages_blocked, links, main_album_id, main_section, market, member_status, members_count, place, public_date_label, site, start_date, finish_date, status, trending, verified, wiki_page"
//            dictionary["fields"] = [fieldsUser, fieldsGroup].joined(separator: ", ")
//        }
//        switch owner {
//        case .domain(let domain):
//            dictionary["domain"] = domain
//        case .id(let id):
//            if case .some(let owner_id) = id {
//                dictionary["owner_id"] = "\(owner_id)"
//            }
//        }
//        return dictionary
//    }
//}
//
//extension Method.Wall.Get: StrategyType {
//
//    public var api: AnyApi<Method.Wall.Get.Response> {
//        return AnyApi(api: self)
//    }
//}
<file_sep>import Foundation

public extension Object {
    /// информация о городе
    public struct City: Codable {
        /// идентификатор города
        public let id: Int?
        /// название города
        public let title: String?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий аудиозапись
    public struct Audio: Codable {
        /// идентификатор альбома, в котором находится аудиозапись
        public let album_id: Int?
        /// исполнитель
        public let artist: String?
        /// запрещенный контент
        public let content_restricted: Object.Positive?
        /// дата добавления
        public let date: Int?
        /// длительность аудиозаписи в секундах
        public let duration: Int?
        /// идентификатор жанра из списка аудио жанров
        public let genre_id: Int?
        /// идентификатор аудиозаписи
        public let id: Int?
        /// аудио в высоком качестве
        public let is_hq: Bool?
        /// идентификатор текста аудиозаписи
        public let lyrics_id: Int?
        /// включена опция «Не выводить при поиске»
        public let no_search: Object.Positive?
        /// идентификатор владельца аудиозаписи
        public let owner_id: Int?
        /// название композиции
        public let title: String?
        /// ссылка на mp3
        public let url: String?
    }
}
<file_sep>import Moya
///
private struct Temp: Decodable {
    
    let error: Error
}
/// Результат запроса
public enum Output<V> where V: Decodable {
    /// Ошибка
    case fault(Fault)
    /// Значение
    case value(V)
    
    static func with<S>(response: Moya.Response, strategy: S) -> Output<V> where S: Strategy, S.Value == V  {
        assert(Thread.isMainThread == false)
        switch response.statusCode {
        case 200 ... 399:
            let data = response.data
            do {
                let raw: S.Raw = try JSONDecoder().decode(S.Raw.self, from: data)
                let value = strategy.transform(raw)
                return Output.value(value)
            } catch let error as Swift.DecodingError {
                guard case .keyNotFound(let key, _) = error, key.stringValue == "response" else {
                    let fault = Fault(data: data, error: error)
                    return Output<V>.fault(fault)
                }
                do {
                    let error = try JSONDecoder().decode(Temp.self, from: data).error
                    let fault = Fault.vkontakte(error)
                    return Output<V>.fault(fault)
                } catch let error as Swift.DecodingError {
                    guard case .keyNotFound(let key, _) = error, key.stringValue == "error" else {
                        let fault = Fault(data: data, error: error)
                        return Output<V>.fault(fault)
                    }
                    let fault = Fault.response
                    return Output<V>.fault(fault)
                } catch let error {
                    let fault = Fault(data: data, error: error)
                    return Output<V>.fault(fault)
                }
            } catch let error {
                let fault = Fault(data: data, error: error)
                return Output<V>.fault(fault)
            }
        default:
            assertionFailure()
            let fault = Fault.unknown(code: response.statusCode, data: response.data)
            return Output<V>.fault(fault)
        }
    }

    public var fault: Fault? {
        switch self {
        case .fault(let value):
            return value
        default:
            return nil
        }
    }
    
    public var value: V? {
        switch self {
        case .value(let value):
            return value
        default:
            return nil
        }
    }
}
<file_sep>import Foundation

/// объекты
public struct Object {

    public struct Items<T>: Decodable where T: Decodable {
        
        public let count: Int
        public let items: [T]
    }
    
    public struct Response<T>: Decodable where T: Decodable {
        
        let response: T
    }
}
<file_sep>import Foundation

public extension Object {
    /// pretty_cards
    public struct PrettyCards: Codable {
        ///
        public struct Card: Codable {
            ///
            public let button: Object.Button?
            ///
            public let card_id: String?
            ///
            public let images: [Object.Image]?
            ///
            public let link_url: String?
            ///
            public let link_url_target: String?
            ///
            public let price: String?
            ///
            public let title: String?
        }
        ///
        public let cards: [Object.PrettyCards.Card]?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий видеозапись
    public struct Profile: Codable {
        /// информация о карьере пользователя
        public struct Career: Codable {
            /// идентификатор сообщества (если доступно)
            public let group_id: Int?
            /// название компании (если доступно)
            public let company: String?
            /// идентификатор страны
            public let country_id: Int?
            /// идентификатор города (если доступно)
            public let city_id: Int?
            /// название города (если доступно)
            public let city_name: String?
            /// год начала работы
            public let from: Int?
            /// год окончания работы
            public let until: Int?
            /// должность
            public let position: String?
        }
        /// количество различных объектов у пользователя
        public struct Counters: Codable {
            /// количество фотоальбомов
            public let albums: Int?
            /// количество аудиозаписей
            public let audios: Int?
            /// количество подписчиков
            public let followers: Int?
            /// количество друзей
            public let friends: Int?
            /// количество сообществ
            public let groups: Int?
            /// количество общих друзей
            public let mutual_friends: Int?
            /// количество заметок
            public let notes: Int?
            /// количество друзей онлайн
            public let online_friends: Int?
            /// количество объектов в блоке «Интересные страницы»
            public let pages: Int?
            /// количество фотографий
            public let photos: Int?
            /// количество подписок (только пользователи)
            public let subsсriptions: Int?
            /// количество фотографий с пользователем
            public let user_photos: Int?
            /// количество видеозаписей с пользователем
            public let user_videos: Int?
            /// количество видеозаписей
            public let videos: Int?
        }
        /// данные о точках, по которым вырезаны профильная и миниатюрная фотографии пользователя
        public struct CropPhoto: Codable {
            /// вырезанная фотография пользователя
            public struct Rect: Codable {
                /// координата X левого верхнего угла в процентах
                public let x: Double?
                /// координата Y левого верхнего угла в процентах
                public let y: Double?
                /// координата X правого нижнего угла в процентах
                public let x2: Double?
                /// координата Y правого нижнего угла в процентах
                public let y2: Double?
            }
            /// вырезанная фотография пользователя
            public let crop: Object.Profile.CropPhoto.Rect?
            /// объект фотографии пользователя, из которой вырезается главное фото профиля
            public let photo: Object.Photo?
            /// миниатюрная квадратная фотография, вырезанная из фотографии crop
            public let rect: Object.Profile.CropPhoto.Rect?
        }
        /// статус дружбы с пользователем
        public enum FriendStatus: Codable {
            /// не является другом
            case notFriend
            /// отправлена заявка/подписка пользователю
            case requestSent
            /// имеется входящая заявка/подписка от пользователя
            case incomingRequest
            /// является другом
            case isFriend
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 0:
                    self = .notFriend
                case 1:
                    self = .requestSent
                case 2:
                    self = .incomingRequest
                case 3:
                    self = .isFriend
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .notFriend:
                    return 0
                case .requestSent:
                    return 1
                case .incomingRequest:
                    return 2
                case .isFriend:
                    return 3
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Profile.FriendStatus(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// время последнего посещения
        public struct LastSeen: Codable {
            /// тип платформы
            public enum Platform: Codable {
                /// мобильная версия
                case mobileVersion
                /// приложение для iPhone
                case iPhone
                /// приложение для iPad
                case iPad
                /// приложение для Android
                case android
                /// приложение для Windows Phone
                case windowsPhone
                /// приложение для Windows 10
                case windows10
                /// полная версия сайта
                case fullSiteVersion
                /// VK Mobile
                case vkMobile
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .mobileVersion
                    case 2:
                        self = .iPhone
                    case 3:
                        self = .iPad
                    case 4:
                        self = .android
                    case 5:
                        self = .windowsPhone
                    case 6:
                        self = .windows10
                    case 7:
                        self = .fullSiteVersion
                    case 8:
                        self = .vkMobile
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .mobileVersion:
                        return 1
                    case .iPhone:
                        return 2
                    case .iPad:
                        return 3
                    case .android:
                        return 4
                    case .windowsPhone:
                        return 5
                    case .windows10:
                        return 6
                    case .fullSiteVersion:
                        return 7
                    case .vkMobile:
                        return 8
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.LastSeen.Platform(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// тип платформы
            public let platform: Object.Profile.LastSeen.Platform?
            /// время последнего посещения в формате Unixtime
            public let time: Int?
        }
        /// информация о военной службе пользователя
        public struct Military: Codable {
            /// идентификатор страны, в которой находится часть
            public let country_id: Int?
            /// год начала службы
            public let from: Int?
            /// номер части
            public let unit: String?
            /// идентификатор части в базе данных
            public let unit_id: Int?
            /// год окончания службы
            public let until: Int?
        }
        /// информация о текущем роде занятия пользователя
        public struct Occupation: Codable {
            /// тип
            public enum Typе: String, Codable {
                /// среднее образование
                case school
                /// высшее образование
                case university
                /// работа
                case work
            }
            /// идентификатор школы, вуза, сообщества компании (в которой пользователь работает)
            public let id: Int?
            /// название школы, вуза или места работы
            public let name: String?
            /// тип
            public let type: Object.Profile.Occupation.Typе?
        }
        /// информация о полях из раздела «Жизненная позиция»
        public struct Personal: Codable {
            /// отношение к алкоголю
            public enum Alcohol: Codable {
                /// резко негативное
                case very_negative
                /// негативное
                case negative
                /// компромиссное
                case neutral
                /// нейтральное
                case compromisable
                /// положительное
                case positive
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .very_negative
                    case 2:
                        self = .negative
                    case 3:
                        self = .neutral
                    case 4:
                        self = .compromisable
                    case 5:
                        self = .positive
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .very_negative:
                        return 1
                    case .negative:
                        return 2
                    case .neutral:
                        return 3
                    case .compromisable:
                        return 4
                    case .positive:
                        return 5
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.Personal.Alcohol(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// главное в жизни
            public enum LifeMain: Codable {
                /// семья и дети
                case family_children
                /// карьера и деньги
                case career_money
                /// развлечения и отдых
                case entertainment_leisure
                /// наука и исследования
                case science_research
                /// совершенствование мира
                case improving_the_world
                /// саморазвитие
                case personal_development
                /// красота и искусство
                case beauty_art
                /// слава и влияние
                case fame_influence
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .family_children
                    case 2:
                        self = .career_money
                    case 3:
                        self = .entertainment_leisure
                    case 4:
                        self = .science_research
                    case 5:
                        self = .improving_the_world
                    case 6:
                        self = .personal_development
                    case 7:
                        self = .beauty_art
                    case 8:
                        self = .fame_influence
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .family_children:
                        return 1
                    case .career_money:
                        return 2
                    case .entertainment_leisure:
                        return 3
                    case .science_research:
                        return 4
                    case .improving_the_world:
                        return 5
                    case .personal_development:
                        return 6
                    case .beauty_art:
                        return 7
                    case .fame_influence:
                        return 8
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.Personal.LifeMain(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// главное в людях
            public enum PeopleMain: Codable {
                /// ум и креативность
                case intellect_creativity
                /// доброта и честность
                case kindness_honesty
                /// красота и здоровье
                case health_beauty
                /// власть и богатство
                case wealth_power
                /// смелость и упорство
                case courage_persistance
                /// юмор и жизнелюбие
                case humor_love_for_life
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .intellect_creativity
                    case 2:
                        self = .kindness_honesty
                    case 3:
                        self = .health_beauty
                    case 4:
                        self = .wealth_power
                    case 5:
                        self = .courage_persistance
                    case 6:
                        self = .humor_love_for_life
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .intellect_creativity:
                        return 1
                    case .kindness_honesty:
                        return 2
                    case .health_beauty:
                        return 3
                    case .wealth_power:
                        return 4
                    case .courage_persistance:
                        return 5
                    case .humor_love_for_life:
                        return 6
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.Personal.PeopleMain(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// политические предпочтения
            public enum Political: Codable {
                /// коммунистические
                case communist
                /// социалистические
                case socialist
                /// умеренные
                case moderate
                /// либеральные
                case liberal
                /// консервативные
                case conservative
                /// монархические
                case monarchist
                /// ультраконсервативные
                case ultraconservative
                /// индифферентные
                case apathetic
                /// либертарианские
                case libertarian
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .communist
                    case 2:
                        self = .socialist
                    case 3:
                        self = .moderate
                    case 4:
                        self = .liberal
                    case 5:
                        self = .conservative
                    case 6:
                        self = .monarchist
                    case 7:
                        self = .ultraconservative
                    case 8:
                        self = .apathetic
                    case 9:
                        self = .libertarian
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .communist:
                        return 1
                    case .socialist:
                        return 2
                    case .moderate:
                        return 3
                    case .liberal:
                        return 4
                    case .conservative:
                        return 5
                    case .monarchist:
                        return 6
                    case .ultraconservative:
                        return 7
                    case .apathetic:
                        return 8
                    case .libertarian:
                        return 9
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.Personal.Political(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// отношение к курению
            public enum Smoking: Codable {
                /// резко негативное
                case very_negative
                /// негативное
                case negative
                /// компромиссное
                case neutral
                /// нейтральное
                case compromisable
                /// положительное
                case positive
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 1:
                        self = .very_negative
                    case 2:
                        self = .negative
                    case 3:
                        self = .neutral
                    case 4:
                        self = .compromisable
                    case 5:
                        self = .positive
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .very_negative:
                        return 1
                    case .negative:
                        return 2
                    case .neutral:
                        return 3
                    case .compromisable:
                        return 4
                    case .positive:
                        return 5
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.Personal.Smoking(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// отношение к алкоголю
            public let alcohol: Object.Profile.Personal.Alcohol?
            /// источники вдохновения
            public let inspired_by: String?
            /// языки
            public let langs: [String]?
            /// главное в жизни
            public let life_main: Object.Profile.Personal.LifeMain?
            /// мировоззрение
            public let religion: String?
            /// главное в людях
            public let people_main: Object.Profile.Personal.PeopleMain?
            /// политические предпочтения
            public let political: Object.Profile.Personal.Political?
            /// отношение к курению
            public let smoking: Object.Profile.Personal.Smoking?
        }
        /// семейное положение пользователя
        public enum Relation: Codable {
            /// не женат/не замужем
            case single
            /// есть друг/есть подруга
            case in_relationship
            ///  помолвлен/помолвлена
            case engaged
            /// женат/замужем
            case married
            /// всё сложно
            case complicated
            /// в активном поиске
            case actively_searching
            /// влюблён/влюблена
            case in_love
            /// в гражданском браке
            case civil_union
            /// не указано
            case not_specified
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 1:
                    self = .single
                case 2:
                    self = .in_relationship
                case 3:
                    self = .engaged
                case 4:
                    self = .married
                case 5:
                    self = .complicated
                case 6:
                    self = .actively_searching
                case 7:
                    self = .in_love
                case 8:
                    self = .civil_union
                case 0:
                    self = .not_specified
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .single:
                    return 1
                case .in_relationship:
                    return 2
                case .engaged:
                    return 3
                case .married:
                    return 4
                case .complicated:
                    return 5
                case .actively_searching:
                    return 6
                case .in_love:
                    return 7
                case .civil_union:
                    return 8
                case .not_specified:
                    return 0
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Profile.Relation(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// пользователь в семейном положении
        public struct RelationPartner: Codable {
            /// фамилия
            public let first_name: String?
            /// идентификатор пользователя
            public let id: Int?
            /// имя
            public let last_name: String?
        }
        /// родственник текущего пользователя
        public struct Relative: Codable {
            /// тип родственной связи
            public enum Typе: String, Codable {
                /// сын/дочь
                case child
                /// внук/внучка
                case grandchild
                /// дедушка/бабушка
                case grandparent
                /// отец/мать
                case parent
                /// брат/сестра
                case sibling
            }
            /// идентификатор пользователя
            public let id: Int?
            /// имя родственника
            public let name: String?
            /// тип родственной связи
            public let type: Object.Profile.Relative.Typе?
        }
        /// список школ, в которых учился пользователь
        public struct School: Codable {
            /// идентификатор типа
            public enum Typе: Codable {
                /// школа
                case school
                /// гимназия
                case gymnasium
                /// лицей
                case lyceum
                /// школа-интернат
                case boarding_school
                /// школа вечерняя
                case evening_school
                /// школа музыкальная
                case music_school
                /// школа спортивная
                case sport_school
                /// школа художественная
                case artistic_school
                /// колледж
                case college
                /// профессиональный лицей
                case professional_lyceum
                /// техникум
                case technical_college
                /// ПТУ
                case vocational
                /// училище
                case specialized_school
                /// школа искусств
                case art_school
                /// детский сад
                case kindergarten
                /// проф. училище
                case professional_institute
                /// автошкола
                case driving_school
                /// неизвестное значение
                case exception(Int)
                
                init(rawValue: Int) {
                    switch rawValue {
                    case 0:
                        self = .school
                    case 1:
                        self = .gymnasium
                    case 2:
                        self = .lyceum
                    case 3:
                        self = .boarding_school
                    case 4:
                        self = .evening_school
                    case 5:
                        self = .music_school
                    case 6:
                        self = .sport_school
                    case 7:
                        self = .artistic_school
                    case 8:
                        self = .college
                    case 9:
                        self = .professional_lyceum
                    case 10:
                        self = .technical_college
                    case 11:
                        self = .vocational
                    case 12:
                        self = .specialized_school
                    case 13:
                        self = .art_school
                    case 14:
                        self = .kindergarten
                    case 15:
                        self = .professional_institute
                    case 16:
                        self = .driving_school
                    default:
                        self = .exception(rawValue)
                    }
                }
                
                public var rawValue: Int {
                    switch self {
                    case .school:
                        return 0
                    case .gymnasium:
                        return 1
                    case .lyceum:
                        return 2
                    case .boarding_school:
                        return 3
                    case .evening_school:
                        return 4
                    case .music_school:
                        return 5
                    case .sport_school:
                        return 6
                    case .artistic_school:
                        return 7
                    case .college:
                        return 8
                    case .professional_lyceum:
                        return 9
                    case .technical_college:
                        return 10
                    case .vocational:
                        return 11
                    case .specialized_school:
                        return 12
                    case .art_school:
                        return 13
                    case .kindergarten:
                        return 14
                    case .professional_institute:
                        return 15
                    case .driving_school:
                        return 16
                    case .exception(let value):
                        return value
                    }
                }
                
                public init(from decoder: Decoder) throws {
                    var container = try decoder.singleValueContainer()
                    let rawValue: Int = try container.decode()
                    self = Object.Profile.School.Typе(rawValue: rawValue)
                }
                
                public func encode(to encoder: Encoder) throws {
                    var container = encoder.singleValueContainer()
                    try container.encode(rawValue)
                }
            }
            /// идентификатор школы
            public let id: String?
            /// идентификатор города, в котором расположена школа
            public let city: Int?
            /// буква класса
            public let `class`: String?
            /// идентификатор страны, в которой расположена школа
            public let country: Int?
            /// наименование школы
            public let name: String?
            /// специализация
            public let speciality: String?
            /// идентификатор типа
            public let type: Object.Profile.School.Typе?
            /// название типа (локализованное?)
            public let type_str: String?
            /// год начала обучения
            public let year_from: Int?
            /// год выпуска
            public let year_graduated: Int?
            /// год окончания обучения
            public let year_to: Int?
        }
        /// пол пользователя
        public enum Sex: Codable {
            /// женский
            case female
            /// мужской
            case male
            /// пол не указан
            case not_specified
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 1:
                    self = .female
                case 2:
                    self = .male
                case 0:
                    self = .not_specified
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .female:
                    return 1
                case .male:
                    return 2
                case .not_specified:
                    return 0
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Profile.Sex(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// вуз, в котором учился пользователь
        public struct University: Codable {
            /// идентификатор кафедры
            public let chair: Int?
            /// наименование кафедры
            public let chair_name: String?
            /// идентификатор города, в котором расположен университет
            public let city: Int?
            /// идентификатор страны, в которой расположен университет
            public let country: Int?
            /// форма обучения
            public let education_form: String?
            /// статус (например, «Выпускник (специалист)»)
            public let education_status: String?
            /// идентификатор факультета
            public let faculty: Int?
            /// наименование факультета
            public let faculty_name: String?
            /// год окончания обучения
            public let graduation: Int?
            /// идентификатор университета
            public let id: Int?
            /// наименование университета
            public let name: String?
        }
        /// содержимое поля «О себе» из профиля
        public let about: String?
        /// содержимое поля «Деятельность» из профиля
        public let activities: String?
        /// содержимое поля «Деятельность» из профиля
        public let activity: String?
        /// дата рождения. Возвращается в формате D.M.YYYY или D.M (если год рождения скрыт). Если дата рождения скрыта целиком, поле отсутствует в ответе
        public let bdate: String?
        /// информация о том, находится ли текущий пользователь в черном списке
        public let blacklisted: Object.Boolean?
        /// информация о том, находится ли пользователь в черном списке у текущего пользователя
        public let blacklisted_by_me: Object.Boolean?
        /// содержимое поля «Любимые книги» из профиля пользователя
        public let books: String?
        /// информация о том, может ли текущий пользователь оставлять записи на стене
        public let can_post: Object.Boolean?
        /// информация о том, может ли текущий пользователь видеть чужие записи на стене
        public let can_see_all_posts: Object.Boolean?
        /// информация о том, может ли текущий пользователь видеть аудиозаписи
        public let can_see_audio: Object.Boolean?
        /// информация о том, будет ли отправлено уведомление пользователю о заявке в друзья от текущего пользователя
        public let can_send_friend_request: Object.Boolean?
        /// информация о том, может ли текующий пользователь загружать документы
        public let can_upload_doc: Object.Boolean?
        /// информация о том, может ли текущий пользователь отправить личное сообщение
        public let can_write_private_message: Object.Boolean?
        /// информация о карьере пользователя
        public let career: [Object.Profile.Career]?
        /// информация о городе, указанном на странице пользователя в разделе «Контакты»
        public let city: Object.City?
        /// количество общих друзей с текущим пользователем
        public let common_count: Int?
        /// количество различных объектов у пользователя
        public let counters: Object.Profile.Counters?
        /// информация о стране, указанной на странице пользователя в разделе «Контакты»
        public let country: Object.Country?
        /// данные о точках, по которым вырезаны профильная и миниатюрная фотографии пользователя
        public let crop_photo: Object.Profile.CropPhoto?
        /// если страница пользователя удалена или заблокирована, то содержит значение deleted или banned
        public let deactivated: String?
        /// короткий адрес страницы. Возвращается строка, содержащая короткий адрес страницы (например, andrew). Если он не назначен, возвращается "id"+user_id, например, id35828305
        public let domain: String?
        /// форма обучения
        public let education_form: String?
        /// статус (например, «Выпускник (специалист)»)
        public let education_status: String?
        /// facebook
        public let facebook: String?
        /// facebook_name
        public let facebook_name: String?
        /// идентификатор факультета
        public let faculty: Int?
        /// название факультета
        public let faculty_name: String?
        /// год окончания
        public let graduation: Int?
        /// имя пользователя
        public let first_name: String
        /// имя пользователя в предложном падеже
        public let first_name_abl: String?
        /// имя пользователя в винительном падеже
        public let first_name_acc: String?
        /// имя пользователя в дательном падеже
        public let first_name_dat: String?
        /// имя пользователя в родительном падеже
        public let first_name_gen: String?
        /// имя пользователя в творительном падеже
        public let first_name_ins: String?
        /// имя пользователя в именительном падеже
        public let first_name_nom: String?
        /// количество подписчиков пользователя
        public let followers_count: Int?
        /// статус дружбы с пользователем
        public let friend_status: Object.Profile.FriendStatus?
        /// содержимое поля «Любимые игры» из профиля
        public let games: String?
        /// информация о том, известен ли номер мобильного телефона пользователя
        public let has_mobile: Object.Boolean?
        /// пользователь установил фотографию для профиля
        public let has_photo: Object.Boolean?
        /// пользователь установил настройку «Кому в интернете видна моя страница» — «Только пользователям ВКонтакте»
        public let hidden: String?
        /// дополнительный номер телефона пользователя
        public let home_phone: String?
        /// название родного города
        public let home_town: String?
        /// идентификатор пользователя
        public let id: Int
        /// содержимое поля «Интересы» из профиля
        public let interests: String?
        /// instagram
        public let instagram: String?
        /// информация о том, есть ли пользователь в закладках у текущего пользователя
        public let is_favorite: Object.Boolean?
        /// информация о том, является ли пользователь другом текущего пользователя
        public let is_friend: Object.Boolean?
        /// информация о том, скрыт ли пользователь из ленты новостей текущего пользователя
        public let is_hidden_from_feed: Object.Boolean?
        /// фамилия пользователя
        public let last_name: String
        /// фамилия пользователя в предложном падеже
        public let last_name_abl: String?
        /// фамилия пользователя в винительном падеже
        public let last_name_acc: String?
        /// фамилия пользователя в дательном падеже
        public let last_name_dat: String?
        /// фамилия пользователя в родительном падеже
        public let last_name_gen: String?
        /// фамилия пользователя в творительном падеже
        public let last_name_ins: String?
        /// фамилия пользователя в именительном падеже
        public let last_name_nom: String?
        /// время последнего посещения
        public let last_seen: Object.Profile.LastSeen?
        /// разделенные запятой идентификаторы списков друзей, в которых состоит пользователь
        public let lists: String?
        /// livejournal
        public let livejournal: String?
        /// девичья фамилия
        public let maiden_name: String?
        /// информация о военной службе пользователя
        public let military: [Object.Profile.Military]?
        /// номер мобильного телефона пользователя
        public let mobile_phone: String?
        /// содержимое поля «Любимые фильмы» из профиля пользователя
        public let movies: String?
        /// содержимое поля «Любимая музыка» из профиля пользователя
        public let music: String?
        /// никнейм (отчество) пользователя
        public let nickname: String?
        /// информация о текущем роде занятия пользователя
        public let occupation: Object.Profile.Occupation?
        /// информация о том, находится ли пользователь сейчас на сайте
        public let online: Object.Boolean?
        /// идентификатор используемого приложения
        public let online_app: String?
        /// пользователь использует мобильное приложение либо мобильную версию сайта
        public let online_mobile: Object.Boolean?
        /// информация о полях из раздела «Жизненная позиция»
        public let personal: Object.Profile.Personal?
        /// url квадратной фотографии пользователя, имеющей ширину 100 пикселей
        public let photo_100: String?
        /// url квадратной фотографии пользователя, имеющей ширину 200 пикселей
        public let photo_200: String?
        /// url фотографии пользователя, имеющей ширину 200 пикселей
        public let photo_200_orig: String?
        /// url фотографии пользователя, имеющей ширину 400 пикселей
        public let photo_400_orig: String?
        /// url квадратной фотографии пользователя, имеющей ширину 50 пикселей
        public let photo_50: String?
        /// строковый идентификатор главной фотографии профиля пользователя в формате {user_id}_{photo_id}, например, 6492_192164258
        public let photo_id: String?
        /// url квадратной фотографии пользователя с максимальной шириной
        public let photo_max: String?
        /// url фотографии пользователя максимального размера. Может быть возвращена фотография, имеющая ширину как 400, так и 200 пикселей
        public let photo_max_orig: String?
        /// любимые цитаты
        public let quotes: String?
        /// семейное положение пользователя
        public let relation: Object.Profile.Relation?
        /// пользователь в семейном положении
        public let relation_partner: Object.Profile.RelationPartner?
        /// список родственников текущего пользователя
        public let relatives: [Object.Profile.Relative]?
        /// список школ, в которых учился пользователь
        public let schools: [Object.Profile.School]?
        /// короткое имя страницы пользователя
        public let screen_name: String?
        /// пол пользователя
        public let sex: Object.Profile.Sex?
        /// адрес сайта, указанный в профиле сайт пользователя
        public let site: String?
        /// skype
        public let skype: String?
        /// строка, содержащая текст статуса, расположенного в профиле под именем пользовател
        public let status: String?
        /// информация о транслируемой композиции
        public let status_audio: Object.Audio?
        /// временная зона пользователя
        public let timezone: Int?
        /// информация о том, есть ли на странице пользователя «огонёк»
        public let trending: Object.Boolean?
        /// любимые телешоу
        public let tv: String?
        /// twitter
        public let twitter: String?
        /// список вузов, в которых учился пользователь
        public let universities: [Object.Profile.University]?
        /// идентификатор университета
        public let university: Int?
        /// название университета
        public let university_name: String?
        /// страница пользователя верифицирована
        public let verified: Object.Boolean?
        /// информация о том, включены ли комментарии на стене
        public let wall_comments: Object.Boolean?
    }
}

<file_sep>import Foundation

public extension Object {
    /// прикрепленная ссылка
    public struct Link: Codable {
        ///
        public struct Rating: Codable {
            ///
            public let reviews_count: Int?
            ///
            public let stars: Double?
        }
        /// информация о кнопке для перехода
        public let button: Object.Button?
        /// действие для кнопки
        public let button_action: String?
        /// название для кнопки
        public let button_text: String?
        /// подпись ссылки (если имеется)
        public let caption: String?
        /// описание ссылки
        public let description: String?
        /// изображение превью, объект фотографии
        public let photo: Object.Photo?
        /// идентификатор вики-страницы с контентом для предпросмотра содержимого страницы
        public let preview_page: String?
        /// URL страницы с контентом для предпросмотра содержимого страницы
        public let preview_url: String?
        /// информация о продукте
        public let product: Object.Product?
        ///
        public let rating: Object.Link.Rating?
        /// target
        public let target: String?
        /// заголовок ссылки
        public let title: String?
        /// URL ссылки
        public let url: String?
    }
}
<file_sep>import Foundation
import Moya

public enum Fault: Swift.Error {
    /// Base url was incorrect
    case baseUrl
    /// Cancelled by the app
    case cancel
    /// Decoding error
    case decoding(error: Swift.DecodingError?)
    /// Internal Moya error
    case moya(MoyaError)
    /// The Internet connection appears to be offline
    case offline
    /// Some other error
    case other(error: Swift.Error)
    /// Response of unknown type
    case response
    /// Timeout exceeded
    case timeout
    /// Unknown response
    case unknown(code: Int, data: Data)
    /// Ошибка API ВКонтакте
    case vkontakte(Error)
    
    init(data: Data? = nil, error: Swift.Error) {
        assert(Thread.isMainThread == false)
        if let data = data {
            let text = String(data: data, encoding: String.Encoding.utf8) ?? ""
            #if DEBUG
            print("\n\(error)\n" + text)
            #endif
            assertionFailure("\(error)")
        }
        if let error = error as? Fault {
            self = error
            return
        }
        if let error = error as? MoyaError {
            self = .moya(error)
            return
        }
        if let error = error as? Swift.DecodingError {
            self = .decoding(error: error)
            return
        }
        switch (error as NSError).code {
        case -1001:
            self = .timeout
        case -1009:
            self = .offline
        default:
            self = .other(error: error)
        }
    }
}
/// Объект, описывающий ошибку ВКонтакте
public struct Error: Decodable, Swift.Error {
    /// Коды ошибок
    public enum Code: Int, Decodable, Swift.Error {
        /// Произошла неизвестная ошибка
        case error_code_1 = 1
        /// Приложение выключено. Необходимо включить приложение в настройках или использовать тестовый режим
        case error_code_2 = 2
        /// Передан неизвестный метод
        case error_code_3 = 3
        /// Неверная подпись
        case error_code_4 = 4
        /// Авторизация пользователя не удалась
        case error_code_5 = 5
        /// Слишком много запросов в секунду
        case error_code_6 = 6
        /// Нет прав для выполнения этого действия. Проверьте, получены ли нужные права доступа при авторизации
        case error_code_7 = 7
        /// Неверный запрос
        case error_code_8 = 8
        /// Слишком много однотипных действий
        case error_code_9 = 9
        /// Произошла внутренняя ошибка сервера
        case error_code_10 = 10
        /// В тестовом режиме приложение должно быть выключено или пользователь должен быть залогинен
        case error_code_11 = 11
        /// Требуется ввод кода с картинки (Captcha)
        case error_code_14 = 14
        /// Доступ запрещён
        case error_code_15 = 15
        /// Требуется выполнение запросов по протоколу HTTPS
        case error_code_16 = 16
        /// Требуется валидация пользователя
        case error_code_17 = 17
        /// Страница удалена или заблокирована
        case error_code_18 = 18
        /// Данное действие запрещено для не Standalone приложений. Если ошибка возникает несмотря на то, что Ваше приложение имеет тип Standalone, убедитесь, что при авторизации Вы используете redirect_uri=https://oauth.vk.com/blank.html
        case error_code_20 = 20
        /// Данное действие разрешено только для Standalone и Open API приложений
        case error_code_21 = 21
        /// Метод был выключен
        case error_code_23 = 23
        /// Требуется подтверждение со стороны пользователя
        case error_code_24 = 24
        /// Ключ доступа сообщества недействителен
        case error_code_27 = 27
        /// Ключ доступа приложения недействителен
        case error_code_28 = 28
        /// Один из необходимых параметров был не передан или неверен
        case error_code_100 = 100
        /// Неверный API ID приложения
        case error_code_101 = 101
        /// Неверный идентификатор пользователя
        case error_code_113 = 113
        /// Неверный timestamp
        case error_code_150 = 150
        /// Доступ к альбому запрещён
        case error_code_200 = 200
        /// Доступ к аудио запрещён. Убедитесь, что Вы используете верные идентификаторы, и доступ к запрашиваемому контенту для текущего пользователя есть в полной версии сайта
        case error_code_201 = 201
        /// Доступ к группе запрещён. Убедитесь, что текущий пользователь является участником или руководителем сообщества
        case error_code_203 = 203
        /// Альбом переполнен
        case error_code_300 = 300
        /// Действие запрещено. Вы должны включить переводы голосов в настройках приложения
        case error_code_500 = 500
        /// Нет прав на выполнение данных операций с рекламным кабинетом
        case error_code_600 = 600
        /// Произошла ошибка при работе с рекламным кабинетом
        case error_code_603 = 603
    }
    ///
    enum CodingKeys: String, CodingKey {
        
        case code = "error_code"
        case message = "error_msg"
        case parameters = "request_params"
    }
    ///
    public let code: Error.Code?
    ///
    public let message: String?
    ///
    public let parameters: [[String:String]]?
}
<file_sep>import Foundation

public extension Object {
    /// фотография, загруженная напрямую
    public struct PostedPhoto: Codable {
        /// идентификатор фотографии
        public let id: Int?
        /// идентификатор владельца фотографии
        public let owner_id: Int?
        /// URL изображения для предпросмотра
        public let photo_130: String?
        /// URL полноразмерного изображения
        public let photo_604: String?
    }
}
<file_sep>import Foundation

public extension Object {
    /// объект, описывающий документ
    public struct Doc: Codable {
        /// информация для предварительного просмотра документа
        public struct Preview: Codable {
            /// данные об аудиосообщении
            public struct AudioMsg: Codable {
                /// длительность аудиосообщения в секундах
                public let duration: Int?
                /// URL .mp3-файла
                public let link_mp3: String?
                /// URL .ogg-файла
                public let link_ogg: String?
                /// массив значений (integer) для визуального отображения звука
                public let waveform: [Int]?
            }
            /// данные о граффити
            public struct Graffiti: Codable {
                /// высота изображения в px
                public let height: Int?
                /// URL документа с граффити
                public let src: String?
                /// ширина изображения в px
                public let width: Int?
            }
            /// видео для предпросмотра
            public struct Video: Codable {
                /// размер файла
                public let file_size: Int?
                /// ширина
                public let height: Int?
                /// url видеозаписи
                public let src: String?
                /// высота
                public let width: Int?
            }
            /// изображения для предпросмотра
            public struct Photo: Codable {
                /// массив копий изображения в разных размерах
                public let sizes: [Object.Photo.Size]?
            }
            /// данные об аудиосообщении
            public let audio_msg: Object.Doc.Preview.AudioMsg?
            /// данные о граффити
            public let graffiti: Object.Doc.Preview.Graffiti?
            /// изображения для предпросмотра
            public let photo: Object.Doc.Preview.Photo?
            /// видеозапись для предпросмотра
            public let video: Object.Doc.Preview.Video?
        }
        /// тип документа
        public enum Typе: Codable {
            /// текстовые документы
            case text_documents
            /// архивы
            case archives
            /// gif
            case gif
            /// изображения
            case images
            /// аудио
            case audio
            /// видео
            case video
            /// электронные книги
            case e_books
            /// неизвестно
            case unknown
            /// неизвестное значение
            case exception(Int)
            
            init(rawValue: Int) {
                switch rawValue {
                case 1:
                    self = .text_documents
                case 2:
                    self = .archives
                case 3:
                    self = .gif
                case 4:
                    self = .images
                case 5:
                    self = .audio
                case 6:
                    self = .video
                case 7:
                    self = .e_books
                case 8:
                    self = .unknown
                default:
                    self = .exception(rawValue)
                }
            }
            
            public var rawValue: Int {
                switch self {
                case .text_documents:
                    return 1
                case .archives:
                    return 2
                case .gif:
                    return 3
                case .images:
                    return 4
                case .audio:
                    return 5
                case .video:
                    return 6
                case .e_books:
                    return 7
                case .unknown:
                    return 8
                case .exception(let value):
                    return value
                }
            }
            
            public init(from decoder: Decoder) throws {
                var container = try decoder.singleValueContainer()
                let rawValue: Int = try container.decode()
                self = Object.Doc.Typе(rawValue: rawValue)
            }
            
            public func encode(to encoder: Encoder) throws {
                var container = encoder.singleValueContainer()
                try container.encode(rawValue)
            }
        }
        /// ключ доступа к объекту
        public let access_key: String?
        /// дата добавления в формате Unixtime
        public let date: Int?
        /// расширение документа
        public let ext: String?
        /// идентификатор документа
        public let id: Int?
        /// идентификатор пользователя, загрузившего документ
        public let owner_id: Int?
        /// информация для предварительного просмотра документа
        public let preview: Object.Doc.Preview?
        /// размер документа в байтах
        public let size: Int?
        /// название документа
        public let title: String?
        /// тип документа
        public let type: Object.Doc.Typе?
        /// адрес документа, по которому его можно загрузить
        public let url: String?
    }
}
<file_sep>import Foundation

public extension Object {
    /// информация о стране
    public struct Country: Codable {
        /// идентификатор страны
        public let id: Int?
        /// название страны
        public let title: String?
    }
}
<file_sep>import Foundation

extension CodingKey {
    
    static func container(decoder: Decoder) throws -> KeyedDecodingContainer<Self> {
        return try decoder.container(keyedBy: Self.self)
    }
    
    static func container(encoder: Encoder) -> KeyedEncodingContainer<Self> {
        return encoder.container(keyedBy: Self.self)
    }
}
<file_sep>import Foundation

public extension Object {
    /// перечисление, обозначающиее положительный результат
    public enum Positive: Int, Codable {
        /// положительный результат
        case positive = 1
    }
}
<file_sep>import Foundation

public extension Object {
    public struct Poll: Codable {
        /// вариант ответа
        public struct Answer: Codable {
            /// идентификатор ответа
            public let id: Int?
            /// рейтинг ответа
            public let rate: Double?
            /// текст ответа
            public let text: String?
            /// число проголосовавших за этот ответ
            public let votes: Int?
        }
        /// опрос анонимный
        public let anonymous: Object.Boolean?
        /// идентификатор варианта ответа, выбранного текущим пользователем
        public let answer_id: Int?
        /// массив объектов, которые содержат информацию о вариантах ответа
        public let answers: [Object.Poll.Answer]?
        /// дата создания в формате Unixtime
        public let created: Int?
        /// идентификатор опроса для получения информации о нем
        public let id: Int?
        /// идентификатор владельца опроса
        public let owner_id: Int?
        /// текст вопроса
        public let question: String?
        /// количество голосов
        public let votes: Int?
    }
}
<file_sep>//import Foundation
//
//public extension Method.Utils {
//    /// Возвращает статистику переходов по сокращенной ссылке.
//    public struct GetLinkStats {
//        /// интервал
//        public enum Interval: String, Codable {
//            /// час
//            case hour
//            /// день
//            case day
//            /// неделя
//            case week
//            /// месяц
//            case month
//            /// все время с момента создания ссылки
//            case forever
//        }
//        /// ответ
//        public struct Response: Codable {
//            /// входной параметр key
//            public let key: String
//            /// массив объектов, данные о статистике
//            public let stats: [Object.ShortenedLinkStats]
//        }
//        /// ключ доступа к приватной статистике
//        public let access_key: String?
//        /// возвращать расширенную статистику (пол/возраст/страна/город)
//        public let extended: Bool
//        /// единица времени для подсчета статистики
//        public let interval: Method.Utils.GetLinkStats.Interval
//        /// длительность периода для получения статистики в выбранных единицах (из параметра interval)
//        public let intervals_count: UInt
//        /// содержательная часть (символы после "vk.cc")
//        public let key: String
//        /// пользовательские данные
//        public let user: App.User
//        
//        public init(access_key: String? = nil, extended: Bool = false, interval: Method.Utils.GetLinkStats.Interval = .day, intervals_count: UInt = 1, key: String, user: App.User) {
//            self.access_key = access_key
//            self.extended = extended
//            self.interval = interval
//            self.intervals_count = intervals_count
//            self.key = key
//            self.user = user
//        }
//    }
//}
//
//extension Method.Utils.GetLinkStats: ApiType {
//    
//    public var method_name: String {
//        return "utils.getLinkStats"
//    }
//    
//    public var parameters: [String: String] {
//        var dictionary = App.parameters
//        dictionary["access_token"] = user.token
//        dictionary["access_key"] = access_key
//        dictionary["interval"] = interval.rawValue
//        dictionary["intervals_count"] = "\(intervals_count)"
//        dictionary["extended"] = extended ? "1" : "0"
//        dictionary["key"] = key
//        return dictionary
//    }
//}
//
//extension Method.Utils.GetLinkStats: StrategyType {
//    
//    public var api: AnyApi<Method.Utils.GetLinkStats.Response> {
//        return AnyApi(api: self)
//    }
//}
