  

import Foundation
///预览结构体
struct JsonBrowses: Codable {
    ///获取访问数据
    let responseContext:ResponseContext?
    ///抓取的数据_预览首次（无额外参数）获取会调用这个
    let contents:Contents?
    ///抓取的数据_预览再（有额外参数）获取会调用这个
    let continuationContents:ContinuationContents?
    enum CodingKeys: String, CodingKey {
        case responseContext = "responseContext"
        case contents = "contents"
        case continuationContents = "continuationContents"

    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        responseContext = try values.decodeIfPresent(ResponseContext.self, forKey: .responseContext)
        contents = try values.decodeIfPresent(Contents.self, forKey: .contents)
        continuationContents = try values.decodeIfPresent(ContinuationContents.self, forKey: .continuationContents)
    }
    
    //MARK: - 内容结构
    ///访问数据
    struct ResponseContext: Codable {
        let visitorData:String?
        enum CodingKeys: String, CodingKey {
            case visitorData = "visitorData"

        }

        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            visitorData = try values.decodeIfPresent(String.self, forKey: .visitorData)
        }
    }
    ///内容结构一
    struct Contents: Codable {
        let singleColumnBrowseResultsRenderer : SingleColumnBrowseResultsRenderer?
        enum CodingKeys: String, CodingKey {

            case singleColumnBrowseResultsRenderer = "singleColumnBrowseResultsRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            singleColumnBrowseResultsRenderer = try values.decodeIfPresent(SingleColumnBrowseResultsRenderer.self, forKey: .singleColumnBrowseResultsRenderer)
        }
        struct SingleColumnBrowseResultsRenderer: Codable {
            ///通常只有1位数据
            let tabs : [Tab]?
            enum CodingKeys: String, CodingKey {
                case tabs = "tabs"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                tabs = try values.decodeIfPresent([Tab].self, forKey: .tabs)
            }
            struct Tab : Codable {
                let tabRenderer : TabRenderer?
                enum CodingKeys: String, CodingKey {
                    case tabRenderer = "tabRenderer"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    tabRenderer = try values.decodeIfPresent(TabRenderer.self, forKey: .tabRenderer)
                }
                struct TabRenderer : Codable {
                    ///内容总汇（包含content以及第一阶段ctoke吗）
                    let content : Content?
                    let trackingParams : String?
                    enum CodingKeys: String, CodingKey {
                        case content = "content"
                        case trackingParams = "trackingParams"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        content = try values.decodeIfPresent(Content.self, forKey: .content)
                        trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams)
                    }
                    struct Content : Codable {
                        let sectionListRenderer : SectionListRenderer?
                        enum CodingKeys: String, CodingKey {
                            case sectionListRenderer = "sectionListRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            sectionListRenderer = try values.decodeIfPresent(SectionListRenderer.self, forKey: .sectionListRenderer)
                        }
                        //MARK: - 核心内容，从此往上代码无意义
                        struct SectionListRenderer : Codable {
                            ///指向图像数据内容
                            let contents : [Content]?
                            ///指向续页编码
                            let continuations : [Continuation]?
                            let trackingParams : String?

                            enum CodingKeys: String, CodingKey {
                                case contents = "contents"
                                case continuations = "continuations"
                                case trackingParams = "trackingParams"
                            }

                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                                continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations)
                                trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams)
                            }
                            ///图像数据内容
                            struct Content: Codable {
                                let musicCarouselShelfRenderer:MusicCarouselShelfRenderer?
                                
                                enum CodingKeys: String, CodingKey {
                                    case musicCarouselShelfRenderer = "musicCarouselShelfRenderer"
                                }

                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer)
                                }
                                struct MusicCarouselShelfRenderer: Codable {
                                    ///指向模块标题
                                    let header:Header?
                                    ///指向音乐内容
                                    let contents:[Content]?
                                    enum CodingKeys: String, CodingKey {
                                        case header = "header"
                                        case contents = "contents"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        header = try values.decodeIfPresent(Header.self, forKey: .header)
                                        contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                                    }
                                    ///模块标题
                                    struct Header: Codable {
                                        let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer?
                                        enum CodingKeys: String, CodingKey {
                                            case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer)
                                        }
                                        struct MusicCarouselShelfBasicHeaderRenderer: Codable {
                                            let title:Title?
                                            enum CodingKeys: String, CodingKey {
                                                case title = "title"
                                            }
                                            init(from decoder: Decoder) throws {
                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                title = try values.decodeIfPresent(Title.self, forKey: .title)
                                            }
                                            struct Title: Codable {
                                                ///一般是第0位
                                                let runs:[Run]?
                                                enum CodingKeys: String, CodingKey {
                                                    case runs = "runs"
                                                }
                                                init(from decoder: Decoder) throws {
                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                                                }
                                                
                                                //MARK: - 文本内容，标题/作者/专辑
                                                struct Run: Codable {
                                                    ///关键文本内容（代表各级标题）
                                                    let text:String?
                                                    ///指向预览ID
                                                    let navigationEndpoint: NavigationEndpoint?
                                                    enum CodingKeys: String, CodingKey {
                                                        case text = "text"
                                                        case navigationEndpoint = "navigationEndpoint"
                                                    }
                                                    init(from decoder: Decoder) throws {
                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                        text = try values.decodeIfPresent(String.self, forKey: .text)
                                                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                                                    }
                                                    struct NavigationEndpoint: Codable {
                                                        let browseEndpoint:BrowseEndpoint?
                                                        
                                                        enum CodingKeys: String, CodingKey {
                                                            case browseEndpoint = "browseEndpoint"
                                                        }
                                                        init(from decoder: Decoder) throws {
                                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                                            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                                                            
                                                        }
                                                        //MARK: - 展示内容块的预览内容
                                                        struct BrowseEndpoint: Codable {
                                                            ///预览ID（作者/歌单/专辑都有，关键内容）
                                                            let browseId:String?
                                                            ///预览参数（作者/歌单/专辑具备，关键内容）
                                                            let params:String?
                                                            ///指向预览类型
                                                            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                                                            enum CodingKeys: String, CodingKey {
                                                                case browseId = "browseId"
                                                                case params = "params"
                                                                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                                                            }
                                                            init(from decoder: Decoder) throws {
                                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                                                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                                                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                                                            }
                                                            struct BrowseEndpointContextSupportedConfigs: Codable {
                                                                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                                                                enum CodingKeys: String, CodingKey {
                                                                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                                                                }
                                                                init(from decoder: Decoder) throws {
                                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                                                                }
                                                                //MARK: - Browse类型 作者/歌单/专辑
                                                                struct BrowseEndpointContextMusicConfig: Codable {
                                                                    let pageType:String?
                                                                    enum CodingKeys: String, CodingKey {
                                                                        case pageType = "pageType"
                                                                    }
                                                                    init(from decoder: Decoder) throws {
                                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                    ///音乐内容
                                    struct Content: Codable {
                                        ///常规列表(通常是四组件构成，封面，一级标题，二级标题，三级标题，额外包含ID内容，通常是单曲)
                                        let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer?
                                        ///两行式列表(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容，通常是歌单)
                                        let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer?
                                        enum CodingKeys: String, CodingKey {
                                            case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer"
                                            case musicTwoRowItemRenderer = "musicTwoRowItemRenderer"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer)
                                            musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer)
                                        }
                                    }
                                }
                            }
                            ///续页编码
                            struct Continuation: Codable {
                                let nextContinuationData:NextContinuationData?
                                enum CodingKeys: String, CodingKey {
                                    case nextContinuationData = "nextContinuationData"
                                }

                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData)
                                }
                                //MARK: - 续页编码
                                struct NextContinuationData: Codable {
                                    let continuation:String?
                                    let clickTrackingParams:String?
                                    enum CodingKeys: String, CodingKey {
                                        case continuation = "continuation"
                                        case clickTrackingParams = "clickTrackingParams"
                                    }

                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        continuation = try values.decodeIfPresent(String.self, forKey: .continuation)
                                        clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    ///内容结构二
    struct ContinuationContents: Codable {
        let sectionListContinuation:SectionListContinuation?
        enum CodingKeys: String, CodingKey {
            case sectionListContinuation = "sectionListContinuation"
        }

        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            sectionListContinuation = try values.decodeIfPresent(SectionListContinuation.self, forKey: .sectionListContinuation)
        }
        //MARK: - 核心内容，从此往上代码无意义
        struct SectionListContinuation : Codable {
            ///指向图像数据内容
            let contents : [Content]?
            ///指向续页编码
            let continuations : [Continuation]?
            let trackingParams : String?

            enum CodingKeys: String, CodingKey {
                case contents = "contents"
                case continuations = "continuations"
                case trackingParams = "trackingParams"
            }

            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                continuations = try values.decodeIfPresent([Continuation].self, forKey: .continuations)
                trackingParams = try values.decodeIfPresent(String.self, forKey: .trackingParams)
            }
            ///图像数据内容
            struct Content: Codable {
                let musicCarouselShelfRenderer:MusicCarouselShelfRenderer?
                
                enum CodingKeys: String, CodingKey {
                    case musicCarouselShelfRenderer = "musicCarouselShelfRenderer"
                }

                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    musicCarouselShelfRenderer = try values.decodeIfPresent(MusicCarouselShelfRenderer.self, forKey: .musicCarouselShelfRenderer)
                }
                struct MusicCarouselShelfRenderer: Codable {
                    ///指向模块标题
                    let header:Header?
                    ///指向音乐内容
                    let contents:[Content]?
                    enum CodingKeys: String, CodingKey {
                        case header = "header"
                        case contents = "contents"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        header = try values.decodeIfPresent(Header.self, forKey: .header)
                        contents = try values.decodeIfPresent([Content].self, forKey: .contents)
                    }
                    ///模块标题
                    struct Header: Codable {
                        let musicCarouselShelfBasicHeaderRenderer:MusicCarouselShelfBasicHeaderRenderer?
                        enum CodingKeys: String, CodingKey {
                            case musicCarouselShelfBasicHeaderRenderer = "musicCarouselShelfBasicHeaderRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            musicCarouselShelfBasicHeaderRenderer = try values.decodeIfPresent(MusicCarouselShelfBasicHeaderRenderer.self, forKey: .musicCarouselShelfBasicHeaderRenderer)
                        }
                        struct MusicCarouselShelfBasicHeaderRenderer: Codable {
                            let title:Title?
                            enum CodingKeys: String, CodingKey {
                                case title = "title"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                title = try values.decodeIfPresent(Title.self, forKey: .title)
                            }
                            struct Title: Codable {
                                ///一般是第0位
                                let runs:[Run]?
                                enum CodingKeys: String, CodingKey {
                                    case runs = "runs"
                                }
                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                                }
                                
                                //MARK: - 文本内容，标题/作者/专辑
                                struct Run: Codable {
                                    ///关键文本内容（代表各级标题）
                                    let text:String?
                                    ///指向预览ID
                                    let navigationEndpoint: NavigationEndpoint?
                                    enum CodingKeys: String, CodingKey {
                                        case text = "text"
                                        case navigationEndpoint = "navigationEndpoint"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        text = try values.decodeIfPresent(String.self, forKey: .text)
                                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                                    }
                                    struct NavigationEndpoint: Codable {
                                        let browseEndpoint:BrowseEndpoint?
                                        
                                        enum CodingKeys: String, CodingKey {
                                            case browseEndpoint = "browseEndpoint"
                                        }
                                        init(from decoder: Decoder) throws {
                                            let values = try decoder.container(keyedBy: CodingKeys.self)
                                            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                                            
                                        }
                                        //MARK: - 展示内容块的预览内容
                                        struct BrowseEndpoint: Codable {
                                            ///预览ID（作者/歌单/专辑都有，关键内容）
                                            let browseId:String?
                                            ///预览参数（作者/歌单/专辑具备，关键内容）
                                            let params:String?
                                            ///指向预览类型
                                            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                                            enum CodingKeys: String, CodingKey {
                                                case browseId = "browseId"
                                                case params = "params"
                                                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                                            }
                                            init(from decoder: Decoder) throws {
                                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                                            }
                                            struct BrowseEndpointContextSupportedConfigs: Codable {
                                                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                                                enum CodingKeys: String, CodingKey {
                                                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                                                }
                                                init(from decoder: Decoder) throws {
                                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                                                }
                                                //MARK: - Browse类型 作者/歌单/专辑
                                                struct BrowseEndpointContextMusicConfig: Codable {
                                                    let pageType:String?
                                                    enum CodingKeys: String, CodingKey {
                                                        case pageType = "pageType"
                                                    }
                                                    init(from decoder: Decoder) throws {
                                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    ///音乐内容
                    struct Content: Codable {
                        ///常规列表(通常是四组件构成，封面，一级标题，二级标题，三级标题，额外包含ID内容，通常是单曲)
                        let musicResponsiveListItemRenderer:RootMusicResponsiveListItemRenderer?
                        ///两行式列表(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容，通常是歌单)
                        let musicTwoRowItemRenderer:RootMusicTwoRowItemRenderer?
                        enum CodingKeys: String, CodingKey {
                            case musicResponsiveListItemRenderer = "musicResponsiveListItemRenderer"
                            case musicTwoRowItemRenderer = "musicTwoRowItemRenderer"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            musicResponsiveListItemRenderer = try values.decodeIfPresent(RootMusicResponsiveListItemRenderer.self, forKey: .musicResponsiveListItemRenderer)
                            musicTwoRowItemRenderer = try values.decodeIfPresent(RootMusicTwoRowItemRenderer.self, forKey: .musicTwoRowItemRenderer)
                        }
                    }
                }
            }
            ///续页编码
            struct Continuation: Codable {
                let nextContinuationData:NextContinuationData?
                enum CodingKeys: String, CodingKey {
                    case nextContinuationData = "nextContinuationData"
                }

                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    nextContinuationData = try values.decodeIfPresent(NextContinuationData.self, forKey: .nextContinuationData)
                }
                //MARK: - 续页编码
                struct NextContinuationData: Codable {
                    let continuation:String?
                    let clickTrackingParams:String?
                    enum CodingKeys: String, CodingKey {
                        case continuation = "continuation"
                        case clickTrackingParams = "clickTrackingParams"
                    }

                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        continuation = try values.decodeIfPresent(String.self, forKey: .continuation)
                        clickTrackingParams = try values.decodeIfPresent(String.self, forKey: .clickTrackingParams)
                    }
                }
            }
        }
    }
}

//MARK: - 图像信息数据结构
///单曲/视频结构(通常是四组件构成，封面，一级标题，二级标题，三级标题，额外包含ID内容)
struct RootMusicResponsiveListItemRenderer: Codable {
    ///指向封面图像
    let thumbnail:Thumbnail?
    ///指向标题歌手专辑(通常有3位，0位是标题，1位是歌手，3位是专辑/列表)
    let flexColumns:[FlexColumn]?
    ///指向列表ID和视频ID
    let overlay:Overlay?
    enum CodingKeys: String, CodingKey {
        case thumbnail = "thumbnail"
        case overlay = "overlay"
        case flexColumns = "flexColumns"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
        overlay = try values.decodeIfPresent(Overlay.self, forKey: .overlay)
        flexColumns = try values.decodeIfPresent([FlexColumn].self, forKey: .flexColumns)
    }
    //含有封面图像
    struct Thumbnail: Codable {
        let musicThumbnailRenderer:MusicThumbnailRenderer?
        enum CodingKeys: String, CodingKey {
            case musicThumbnailRenderer = "musicThumbnailRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer)
        }
        
        struct MusicThumbnailRenderer: Codable {
            let thumbnail:Thumbnail?
            enum CodingKeys: String, CodingKey {
                case thumbnail = "thumbnail"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                self.thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
            }
            struct Thumbnail: Codable {
                ///封面图片组（默认取最后一位，图像内容最大最高清）
                let thumbnails:[Thumbnails]?
                enum CodingKeys: String, CodingKey {
                    case thumbnails = "thumbnails"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    self.thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails)
                }
                //MARK: - 封面图片
                ///封面图片
                struct Thumbnails: Codable {
                    ///封面图片路径
                    let url:String?
                    let width:CGFloat?
                    let height:CGFloat?
                    enum CodingKeys: String, CodingKey {
                        case url = "url"
                        case width = "width"
                        case height = "height"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        url = try values.decodeIfPresent(String.self, forKey: .url)
                        width = try values.decodeIfPresent(CGFloat.self, forKey: .width)
                        height = try values.decodeIfPresent(CGFloat.self, forKey: .height)
                    }
                }
            }
        }
    }
    //含有标题作者专辑
    struct FlexColumn: Codable {
        let musicResponsiveListItemFlexColumnRenderer:MusicResponsiveListItemFlexColumnRenderer?
        enum CodingKeys: String, CodingKey {
            case musicResponsiveListItemFlexColumnRenderer = "musicResponsiveListItemFlexColumnRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicResponsiveListItemFlexColumnRenderer = try values.decodeIfPresent(MusicResponsiveListItemFlexColumnRenderer.self, forKey: .musicResponsiveListItemFlexColumnRenderer)
        }
        struct MusicResponsiveListItemFlexColumnRenderer: Codable {
            let text:Text?
            enum CodingKeys: String, CodingKey {
                case text = "text"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(Text.self, forKey: .text)
            }
            struct Text: Codable {
                let runs:[Run]?
                enum CodingKeys: String, CodingKey {
                    case runs = "runs"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    runs = try values.decodeIfPresent([Run].self, forKey: .runs)
                }
                //MARK: - 文本内容，标题/作者/专辑
                struct Run: Codable {
                    ///关键文本内容（代表各级标题）
                    let text:String?
                    ///指向预览ID
                    let navigationEndpoint: NavigationEndpoint?
                    enum CodingKeys: String, CodingKey {
                        case text = "text"
                        case navigationEndpoint = "navigationEndpoint"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        text = try values.decodeIfPresent(String.self, forKey: .text)
                        navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
                    }
                    struct NavigationEndpoint: Codable {
                        let browseEndpoint:BrowseEndpoint?
                        
                        enum CodingKeys: String, CodingKey {
                            case browseEndpoint = "browseEndpoint"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                            
                        }
                        //MARK: - 展示内容块的预览内容
                        struct BrowseEndpoint: Codable {
                            ///预览ID（作者/歌单/专辑都有，关键内容）
                            let browseId:String?
                            ///预览参数（作者/歌单/专辑具备，关键内容）
                            let params:String?
                            ///指向预览类型
                            let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                            enum CodingKeys: String, CodingKey {
                                case browseId = "browseId"
                                case params = "params"
                                case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                            }
                            struct BrowseEndpointContextSupportedConfigs: Codable {
                                let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                                enum CodingKeys: String, CodingKey {
                                    case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                                }
                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                                }
                                //MARK: - Browse类型 作者/歌单/专辑
                                struct BrowseEndpointContextMusicConfig: Codable {
                                    let pageType:String?
                                    enum CodingKeys: String, CodingKey {
                                        case pageType = "pageType"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    //含有列表ID和视频ID
    struct Overlay: Codable {
        let musicItemThumbnailOverlayRenderer:MusicItemThumbnailOverlayRenderer?
        enum CodingKeys: String, CodingKey {
            case musicItemThumbnailOverlayRenderer = "musicItemThumbnailOverlayRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            musicItemThumbnailOverlayRenderer = try values.decodeIfPresent(MusicItemThumbnailOverlayRenderer.self, forKey: .musicItemThumbnailOverlayRenderer)
        }
        struct MusicItemThumbnailOverlayRenderer: Codable {
            let content:Content?
            enum CodingKeys: String, CodingKey {
                case content = "content"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                content = try values.decodeIfPresent(Content.self, forKey: .content)
            }
            struct Content: Codable {
                let musicPlayButtonRenderer:MusicPlayButtonRenderer?
                enum CodingKeys: String, CodingKey {
                    case musicPlayButtonRenderer = "musicPlayButtonRenderer"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    musicPlayButtonRenderer = try values.decodeIfPresent(MusicPlayButtonRenderer.self, forKey: .musicPlayButtonRenderer)
                }
                struct MusicPlayButtonRenderer: Codable {
                    let playNavigationEndpoint:PlayNavigationEndpoint?
                    enum CodingKeys: String, CodingKey {
                        case playNavigationEndpoint = "playNavigationEndpoint"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        playNavigationEndpoint = try values.decodeIfPresent(PlayNavigationEndpoint.self, forKey: .playNavigationEndpoint)
                    }
                    struct PlayNavigationEndpoint: Codable {
                        let watchEndpoint:WatchEndpoint?
                        enum CodingKeys: String, CodingKey {
                            case watchEndpoint = "watchEndpoint"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
                        }
                        
                        //MARK: - 关键内容，视频ID/列表ID/参数
                        struct WatchEndpoint: Codable {
                            ///视频ID
                            let videoId:String?
                            ///视频列表
                            let playlistId:String?
                            ///参数
                            let params:String?
                            ///播放类型
                            let watchEndpointMusicSupportedConfigs:WatchEndpointMusicSupportedConfigs?
                            enum CodingKeys: String, CodingKey {
                                case videoId = "videoId"
                                case playlistId = "playlistId"
                                case params = "params"
                                case watchEndpointMusicSupportedConfigs = "watchEndpointMusicSupportedConfigs"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
                                playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
                                params = try values.decodeIfPresent(String.self, forKey: .params)
                                watchEndpointMusicSupportedConfigs = try values.decodeIfPresent(WatchEndpointMusicSupportedConfigs.self, forKey: .watchEndpointMusicSupportedConfigs)
                            }
                            struct WatchEndpointMusicSupportedConfigs: Codable {
                                let watchEndpointMusicConfig:WatchEndpointMusicConfig?
                                enum CodingKeys: String, CodingKey {
                                    case watchEndpointMusicConfig = "watchEndpointMusicConfig"
                                }
                                init(from decoder: Decoder) throws {
                                    let values = try decoder.container(keyedBy: CodingKeys.self)
                                    watchEndpointMusicConfig = try values.decodeIfPresent(WatchEndpointMusicConfig.self, forKey: .watchEndpointMusicConfig)
                                }
                                //MARK: - 敲定Video类型
                                struct WatchEndpointMusicConfig: Codable {
                                    ///这个值存在，那么这个预览例就是Video，具体是什么由这个值判断
                                    let musicVideoType:String?
                                    enum CodingKeys: String, CodingKey {
                                        case musicVideoType = "musicVideoType"
                                    }
                                    init(from decoder: Decoder) throws {
                                        let values = try decoder.container(keyedBy: CodingKeys.self)
                                        musicVideoType = try values.decodeIfPresent(String.self, forKey: .musicVideoType)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
///列表/专辑结构(通常是三组件构成，封面，一级标题，二级标题，额外包含ID内容)
struct RootMusicTwoRowItemRenderer: Codable {
    ///指向图像内容
    let thumbnailRenderer:ThumbnailRenderer?
    ///指向主标题
    let title:Title?
    ///指向副标题
    let subtitle:Subtitle?
    ///指向列表ID和视频ID
    let thumbnailOverlay:ThumbnailOverlay?
    ///指向视频内容
    let navigationEndpoint:NavigationEndpoint?
    enum CodingKeys: String, CodingKey {
        case thumbnailRenderer = "thumbnailRenderer"
        case title = "title"
        case subtitle = "subtitle"
        case thumbnailOverlay = "thumbnailOverlay"
        case navigationEndpoint = "navigationEndpoint"
    }
    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        self.thumbnailRenderer = try values.decodeIfPresent(ThumbnailRenderer.self, forKey: .thumbnailRenderer)
        self.title = try values.decodeIfPresent(Title.self, forKey: .title)
        self.subtitle = try values.decodeIfPresent(Subtitle.self, forKey: .subtitle)
        self.thumbnailOverlay = try values.decodeIfPresent(ThumbnailOverlay.self, forKey: .thumbnailOverlay)
        self.navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
    }
    struct ThumbnailRenderer: Codable {
        let musicThumbnailRenderer:MusicThumbnailRenderer?
        enum CodingKeys: String, CodingKey {
            case musicThumbnailRenderer = "musicThumbnailRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            self.musicThumbnailRenderer = try values.decodeIfPresent(MusicThumbnailRenderer.self, forKey: .musicThumbnailRenderer)
        }
        struct MusicThumbnailRenderer: Codable {
            let thumbnail:Thumbnail?
            enum CodingKeys: String, CodingKey {
                case thumbnail = "thumbnail"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                self.thumbnail = try values.decodeIfPresent(Thumbnail.self, forKey: .thumbnail)
            }
            struct Thumbnail: Codable {
                ///封面图片组（默认取最后一位，图像内容最大最高清）
                let thumbnails:[Thumbnails]?
                enum CodingKeys: String, CodingKey {
                    case thumbnails = "thumbnails"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    self.thumbnails = try values.decodeIfPresent([Thumbnails].self, forKey: .thumbnails)
                }
                //MARK: - 封面图片
                ///封面图片
                struct Thumbnails: Codable {
                    ///封面图片路径
                    let url:String?
                    let width:CGFloat?
                    let height:CGFloat?
                    enum CodingKeys: String, CodingKey {
                        case url = "url"
                        case width = "width"
                        case height = "height"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        url = try values.decodeIfPresent(String.self, forKey: .url)
                        width = try values.decodeIfPresent(CGFloat.self, forKey: .width)
                        height = try values.decodeIfPresent(CGFloat.self, forKey: .height)
                    }
                }
            }
        }
    }
    struct Title: Codable {
        let runs:[Run]?
        enum CodingKeys: String, CodingKey {
            case runs = "runs"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            self.runs = try values.decodeIfPresent([Run].self, forKey: .runs)
        }
        //MARK: - 文本内容，标题/作者/专辑
        struct Run: Codable {
            ///关键文本内容（代表各级标题）
            let text:String?
            ///指向预览ID
            let navigationEndpoint: NavigationEndpoint?
            enum CodingKeys: String, CodingKey {
                case text = "text"
                case navigationEndpoint = "navigationEndpoint"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(String.self, forKey: .text)
                navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
            }
            struct NavigationEndpoint: Codable {
                let browseEndpoint:BrowseEndpoint?
                
                enum CodingKeys: String, CodingKey {
                    case browseEndpoint = "browseEndpoint"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                    
                }
                //MARK: - 展示内容块的预览内容
                struct BrowseEndpoint: Codable {
                    ///预览ID（作者/歌单/专辑都有，关键内容）
                    let browseId:String?
                    ///预览参数（作者/歌单/专辑具备，关键内容）
                    let params:String?
                    ///指向预览类型
                    let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                    enum CodingKeys: String, CodingKey {
                        case browseId = "browseId"
                        case params = "params"
                        case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                        params = try values.decodeIfPresent(String.self, forKey: .params)
                        browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                    }
                    struct BrowseEndpointContextSupportedConfigs: Codable {
                        let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                        enum CodingKeys: String, CodingKey {
                            case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                        }
                        //MARK: - Browse类型 作者/歌单/专辑
                        struct BrowseEndpointContextMusicConfig: Codable {
                            let pageType:String?
                            enum CodingKeys: String, CodingKey {
                                case pageType = "pageType"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                            }
                        }
                    }
                }
            }
        }
    }
    struct Subtitle: Codable {
        let runs:[Run]?
        enum CodingKeys: String, CodingKey {
            case runs = "runs"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            self.runs = try values.decodeIfPresent([Run].self, forKey: .runs)
        }
        //MARK: - 文本内容，标题/作者/专辑
        struct Run: Codable {
            ///关键文本内容（代表各级标题）
            let text:String?
            ///指向预览ID
            let navigationEndpoint: NavigationEndpoint?
            enum CodingKeys: String, CodingKey {
                case text = "text"
                case navigationEndpoint = "navigationEndpoint"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                text = try values.decodeIfPresent(String.self, forKey: .text)
                navigationEndpoint = try values.decodeIfPresent(NavigationEndpoint.self, forKey: .navigationEndpoint)
            }
            struct NavigationEndpoint: Codable {
                let browseEndpoint:BrowseEndpoint?
                
                enum CodingKeys: String, CodingKey {
                    case browseEndpoint = "browseEndpoint"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    browseEndpoint = try values.decodeIfPresent(BrowseEndpoint.self, forKey: .browseEndpoint)
                    
                }
                //MARK: - 展示内容块的预览内容
                struct BrowseEndpoint: Codable {
                    ///预览ID（作者/歌单/专辑都有，关键内容）
                    let browseId:String?
                    ///预览参数（作者/歌单/专辑具备，关键内容）
                    let params:String?
                    ///指向预览类型
                    let browseEndpointContextSupportedConfigs:BrowseEndpointContextSupportedConfigs?
                    enum CodingKeys: String, CodingKey {
                        case browseId = "browseId"
                        case params = "params"
                        case browseEndpointContextSupportedConfigs = "browseEndpointContextSupportedConfigs"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        browseId = try values.decodeIfPresent(String.self, forKey: .browseId)
                        params = try values.decodeIfPresent(String.self, forKey: .params)
                        browseEndpointContextSupportedConfigs = try values.decodeIfPresent(BrowseEndpointContextSupportedConfigs.self, forKey: .browseEndpointContextSupportedConfigs)
                    }
                    struct BrowseEndpointContextSupportedConfigs: Codable {
                        let browseEndpointContextMusicConfig:BrowseEndpointContextMusicConfig?
                        enum CodingKeys: String, CodingKey {
                            case browseEndpointContextMusicConfig = "browseEndpointContextMusicConfig"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            browseEndpointContextMusicConfig = try values.decodeIfPresent(BrowseEndpointContextMusicConfig.self, forKey: .browseEndpointContextMusicConfig)
                        }
                        //MARK: - Browse类型 作者/歌单/专辑
                        struct BrowseEndpointContextMusicConfig: Codable {
                            let pageType:String?
                            enum CodingKeys: String, CodingKey {
                                case pageType = "pageType"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                pageType = try values.decodeIfPresent(String.self, forKey: .pageType)
                            }
                        }
                    }
                }
            }
        }
    }
    struct ThumbnailOverlay: Codable {
        let musicItemThumbnailOverlayRenderer:MusicItemThumbnailOverlayRenderer?
        enum CodingKeys: String, CodingKey {
            case musicItemThumbnailOverlayRenderer = "musicItemThumbnailOverlayRenderer"
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            self.musicItemThumbnailOverlayRenderer = try values.decodeIfPresent(MusicItemThumbnailOverlayRenderer.self, forKey: .musicItemThumbnailOverlayRenderer)
        }
        struct MusicItemThumbnailOverlayRenderer: Codable {
            let content:Content?
            enum CodingKeys: String, CodingKey {
                case content = "content"
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                self.content = try values.decodeIfPresent(Content.self, forKey: .content)
            }
            struct Content: Codable {
                let musicPlayButtonRenderer:MusicPlayButtonRenderer?
                enum CodingKeys: String, CodingKey {
                    case musicPlayButtonRenderer = "musicPlayButtonRenderer"
                }
                init(from decoder: Decoder) throws {
                    let values = try decoder.container(keyedBy: CodingKeys.self)
                    self.musicPlayButtonRenderer = try values.decodeIfPresent(MusicPlayButtonRenderer.self, forKey: .musicPlayButtonRenderer)
                }
                struct MusicPlayButtonRenderer: Codable {
                    let playNavigationEndpoint:PlayNavigationEndpoint?
                    enum CodingKeys: String, CodingKey {
                        case playNavigationEndpoint = "playNavigationEndpoint"
                    }
                    init(from decoder: Decoder) throws {
                        let values = try decoder.container(keyedBy: CodingKeys.self)
                        self.playNavigationEndpoint = try values.decodeIfPresent(PlayNavigationEndpoint.self, forKey: .playNavigationEndpoint)
                    }
                    struct PlayNavigationEndpoint: Codable {
                        let watchPlaylistEndpoint:WatchPlaylistEndpoint?
                        enum CodingKeys: String, CodingKey {
                            case watchPlaylistEndpoint = "watchPlaylistEndpoint"
                        }
                        init(from decoder: Decoder) throws {
                            let values = try decoder.container(keyedBy: CodingKeys.self)
                            watchPlaylistEndpoint = try values.decodeIfPresent(WatchPlaylistEndpoint.self, forKey: .watchPlaylistEndpoint)
                        }
                        
                        //MARK: - 列表/专辑ID
                        struct WatchPlaylistEndpoint: Codable {
                            ///视频列表
                            let playlistId:String?
                            enum CodingKeys: String, CodingKey {
                                case playlistId = "playlistId"
                            }
                            init(from decoder: Decoder) throws {
                                let values = try decoder.container(keyedBy: CodingKeys.self)
                                playlistId = try values.decodeIfPresent(String.self, forKey: .playlistId)
                            }
                        }
                    }
                }
            }
        }
    }
    struct NavigationEndpoint: Codable {
        let watchEndpoint:WatchEndpoint?
        enum CodingKeys: String, CodingKey {
            case watchEndpoint = "watchEndpoint"
            
        }
        init(from decoder: Decoder) throws {
            let values = try decoder.container(keyedBy: CodingKeys.self)
            self.watchEndpoint = try values.decodeIfPresent(WatchEndpoint.self, forKey: .watchEndpoint)
           
        }
        struct WatchEndpoint: Codable {
            let videoId:String?
            
            enum CodingKeys: String, CodingKey {
                case videoId = "videoId"
                
            }
            init(from decoder: Decoder) throws {
                let values = try decoder.container(keyedBy: CodingKeys.self)
                self.videoId = try values.decodeIfPresent(String.self, forKey: .videoId)
               
            }
        }
    }
}
