目录

自由学习记录43

自由学习记录(43)

https://i-blog.csdnimg.cn/direct/01f547d0381f427788a1315c127be77c.png

不同的服务器可以使用不同协议,但协议本身不会决定服务器的类型

类型特点
物理服务器真实的计算机(如 Dell、HP 服务器)
虚拟服务器运行在云计算平台上的 VM(如 AWS EC2、阿里云 ECS)
容器化服务器通过 Docker / Kubernetes 运行多个轻量级服务

不同协议可以在同一服务器上运行,或者分布在不同服务器上:

协议用途常见服务器
HTTP / HTTPSWeb 访问Nginx、Apache、IIS
FTP / SFTP文件传输vsftpd、FileZilla Server
SMTP / IMAP / POP3邮件通信Postfix、Dovecot
SSH远程登录OpenSSH
WebSocket实时通信Socket.IO、SignalR
服务器类型作用常见软件
Web 服务器处理 HTTP/HTTPS 请求,提供网页Nginx、Apache、IIS
数据库服务器存储和管理数据MySQL、PostgreSQL、MongoDB
应用服务器运行业务逻辑,如 APITomcat、Node.js、Django
文件服务器提供文件存储和访问Samba、FTP 服务器
邮件服务器发送和接收邮件Postfix、Exim、Microsoft Exchange
  • HTTP( 不加密 )和 HTTPS( 加密 )都是基于 TCP/IP应用层协议
  • Web 服务器(如 Nginx、Apache、IIS)可以同时支持 HTTP 和 HTTPS
    • 如果服务器配置了 SSL 证书,就可以使用 HTTPS
    • 如果没有 SSL 证书,只能使用 HTTP

http

https://i-blog.csdnimg.cn/direct/bdea665eb2df43ae93466d02e267cbe1.png

自定义handler类,自己在里面处理数据

https://i-blog.csdnimg.cn/direct/34f587f8921e447bbbce5a9742f6d3de.png

texture也是一样的

https://i-blog.csdnimg.cn/direct/2ee3a4f33c56499b8eb9554c5e6a4695.png

这里的File子类型就是直接下载文件,不用再转成二进制数组来使用

DownloadHandler存在多个可以不同处理返回的数据的子类封装

https://i-blog.csdnimg.cn/direct/ba4b281c327a4a2e8cd8cf12ff228d40.png

https://i-blog.csdnimg.cn/direct/02f9dd8d5d4a429bb2992a2a45267844.png

https://i-blog.csdnimg.cn/direct/cc4d249905164ad5a1cdf75e49cb4281.png

  • awaitasync Task
  • 没有 await → 直接 Task
写法用法是否推荐
public Task<int> GetNumber() { return Task.FromResult(42); }直接返回 Task推荐 (更高效)
public async Task<int> GetNumberAsync() { await Task.Delay(1000); return 42; }需要 await 异步等待推荐
public async Task<int> GetNumber() { return Task.FromResult(42); }async 没发挥作用🚨 不推荐

async 让方法可以使用 await 关键字

async 本身不会让方法变异步 ,它只是告诉编译器:

  • 这个方法 可能 包含异步操作
  • 这个方法的返回值 一定要是 Task / Task<T>void
类型返回值类型await 作用示例
Task无返回值等待任务完成await SomeMethodAsync();
Task<T>返回 T等待任务完成,并获取 T 结果string result = await SomeMethodAsync();
ValueTask<T>返回 TTask<T> 轻量int value = await GetValueAsync();

在 C# 中, await 只能用于 TaskTask<T> 类型 ,因为 await 的作用是等待一个异步任务完成 ,然后获取返回值。

https://i-blog.csdnimg.cn/direct/3a0e77ac74cb47cdbb22380ab9a49419.png

一段很错误的代码

async Task<IEnumerator> GetGPTStreamResponse(string userInput)

IEnumeratorasync 方法 不能直接混用

async 方法不能返回 IEnumeratorCoroutine 只支持 IEnumerator

async Task<IEnumerator> 并不符合 Unity 的 Coroutine 要求


  • await 确保 HTTP 请求完成(但 不会等待完整响应体 )。
  • HttpCompletionOption.ResponseHeadersReadHttpClient 只等 HTTP 头部,而不是整个响应 (适用于流式数据)。

https://i-blog.csdnimg.cn/direct/dce66255e3a641398ad33a0ffcbd438b.png

普通 PostAsync() 不会 立即返回数据,而是等服务器 完全返回后才解析

HttpResponseMessage response = await client.PostAsync(apiUrl, new StringContent(jsonData, Encoding.UTF8, "application/json"));
string responseBody = await response.Content.ReadAsStringAsync(); // ❌ 这里会卡住直到整个响应完成

https://i-blog.csdnimg.cn/direct/f877dce916a7459aabf6ba08ac04f92e.png

关于请求体里的message

https://i-blog.csdnimg.cn/direct/7e9f7977849241108a0390ee16e520cf.png

https://i-blog.csdnimg.cn/direct/ef950d6da7614ed8a59f044c0ec43dc5.png

必须写的请求体

字段作用示例值
model指定使用的 GPT 模型"gpt-4"
messages聊天上下文(数组)[{"role": "user", "content": "Hello"}]

https://i-blog.csdnimg.cn/direct/72003644969245d8b27aae0317a5c6fd.png

但在JSON 内写的数组的顺序是重要的:

{

“messages”: [

{“role”: “user”, “content”: “Hello”},

{“role”: “assistant”, “content”: “Hi! How can I help you?”}

]

}

{

“messages”: [

{“role”: “assistant”, “content”: “Hi! How can I help you?”},

{“role”: “user”, “content”: “Hello”}

]

}

❌ 这两个请求是不同的! OpenAI API 会按照数组的顺序解析 messages,所以调换 user 和 assistant 的顺序会影响对话上下文。

——————

HTTP 请求体(Body)或请求头(Headers)里,字段的前后顺序通常不影响请求的识别,

服务器是按字段名读取的,顺序无关(一些低级 HTTP 代理或老旧的 Web 服务器可能对 Headers 顺序敏感。,但极其少见)

API既会规定请求体里的内容,也会规定请求头里的内容

——

newtonsoft的匿名类写法实际上是借助c#的特殊写法,达到更直观的效果,处理成json字符串

——————

如果 HttpClient 发送的数据格式不对,比如:

少了 Content-Type: application/json

少了 Authorization: Bearer API_KEY

JSON 结构错误

OpenAI 服务器会返回:

{

“error”: {

“message”: “Invalid JSON”,

“type”: “invalid_request_error”,

“code”: 400

}

}

——————

如何保证 HttpClient 发送的格式是正确的?

✅ 1. 通过 OpenAI API 文档 确定请求格式

在 OpenAI API 文档里,规定了正确的请求格式:

{

“model”: “gpt-4”,

“messages”: [{“role”: “user”, “content”: “Hello”}],

“temperature”: 0.7

}

你需要 自己确保 你的 JSON 完全符合这个格式,否则 OpenAI 服务器会返回错误。


✅ 2. 使用 Newtonsoft.Json 确保 JSON 序列化正确

C# 原始字符串拼接 JSON 容易出错,所以推荐用 Newtonsoft.Json 进行 序列化:

using Newtonsoft.Json;

var requestData = new

{

model = “gpt-4”,

messages = new object[]

{

new { role = “user”, content = “Hello!” }

},

temperature = 0.7

};

string jsonData = JsonConvert.SerializeObject(requestData);

这样生成的 JSON 一定是符合 OpenAI API 规则的,不会因为手动写错 JSON 而导致格式错误

——————

HttpClient 不会验证你构造的 JSON 是否符合 OpenAI API 的要求,它只是:

封装 HTTP 请求(处理 TCP 连接、HTTP 头、数据流)

发送你写的 JSON 数据

接收服务器的响应

The C# keyword readonly is used to declare fields that can only be assigned in the constructor or at declaration.

Example:

class Example

{

public readonly int MyValue; // Can only be set in the constructor

public Example(int value)

{

MyValue = value;

}

}

Impact: Used for immutability to prevent changes after initialization.

requireComponent

https://i-blog.csdnimg.cn/direct/a5042d2b131241569006d35604f4d184.jpg

https://i-blog.csdnimg.cn/direct/a5d1b29d721e48cf84ed623d81456f7e.png

本来觉得ai toolbox是非常重要的插件,没有血亏,现在看来也就那样了

解析器(Parser)?

解析器(Parser)是一个 将 JSON 格式的字符串转换为编程语言中的数据结构 的程序或库(newtonsoftJson就是)。

解析的基本过程

  1. 原始 JSON 字符串 (通常是从文件、网络请求或数据库中读取的):

    "{ \"name\": \"Alice\", \"age\": 25, \"skills\": [\"C++\", \"Python\"] }"

解析器的作用

解析器会把 JSON 字符串解析成 编程语言可用的数据结构 ,这样程序可以方便地访问、修改、存储这些数据。

语言解析器库解析后数据类型
C#Newtonsoft.JsonSystem.Text.JsonDictionary<string, object>List<T> ,自定义类
JavaScriptJSON.parse()ObjectArray
Pythonjson.loads()dictlist
JavaGsonJacksonMap<String, Object> ,自定义类
Goencoding/jsonmap[string]interface{} ,结构体

using Newtonsoft.Json;
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string json = "{ \"name\": \"Alice\", \"age\": 25 }";

        // 解析 JSON 字符串为 Dictionary
        Dictionary<string, object> data = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
        Console.WriteLine(data["name"]);  // 输出: Alice
        Console.WriteLine(data["age"]);   // 输出: 25
    }
}

解析后,JSON 变成了 C# 的 Dictionary<string, object> ,可以随时访问 name、age 这些字段。


解析器是如何存储数据的?

解析器不会缓存 JSON,而是仅仅具有这种 JSON 转换为 编程语言的内存数据结构 (如对象、字典、列表等)的能力,没有被结构接下,则无用。

解析后的数据通常存储在:

  • 内存(RAM) 中的 对象、字典、数组 ,可以随时访问。
  • 缓存(Cache) :如果手动存入 Redis、文件、数据库等,就可以缓存起来,方便后续读取。

示例:

// 解析 JSON 成 C# 类
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

string json = "{ \"name\": \"Alice\", \"age\": 25 }";

// 解析成 Person 对象
Person person = JsonConvert.DeserializeObject<Person>(json);
Console.WriteLine(person.Name);  // Alice
Console.WriteLine(person.Age);   // 25

这里 person 存在于 C# 内存 ,你可以随时访问 person.Nameperson.Age

默认情况下Newtonsoft.Json 解析 JSON 时,使用 大小写不敏感 的匹配规则。


什么是达摩 ASR?

达摩 ASR 是阿里巴巴 达摩院 开发的一款 批量离线语音识别(ASR,Automatic Speech Recognition)工具 ,专门用于 高效、精准地转换音频到文本 ,特别适用于 中文语音 的大规模处理场景。

0a-UVR5 人声伴奏分离 & 去混响去延迟工具

1. 为什么叫 0a-UVR5?

这个名称主要来源于 UVR5(Ultimate Vocal Remover 5) ,它是一款开源的 人声伴奏分离工具

  • “0a” 可能是该工具的某个特殊版本或开发者的命名方式 ,但主功能仍然基于 UVR5 的 神经网络模型 ,用于从混音中提取人声或伴奏。

2. 混响是什么?为什么要去混响?

混响(Reverb) 是声音在封闭空间传播时,经过墙壁、地面、天花板等表面反射后产生的回声效果。

  • 例如,在 浴室、体育馆、音乐厅 说话时,声音会持续一段时间,不会立即消失,这就是混响。
  • 去混响(De-Reverb) 在 AI 语音处理中很重要,因为:
    • 提高清晰度 :消除不必要的回声,使声音更干净。
    • 提升模型识别率 :混响会干扰 TTS、语音识别(ASR)、变声 等 AI 任务,使其更难识别语音。
    • 改善语音合成 :让克隆出来的声音更自然、真实,而不是“带着房间回音”。

3. 为什么要去延迟?

在音频处理中, 延迟(Latency) 通常指的是音频信号传输或处理过程中产生的时间滞后。

  • 去延迟(De-Delay) 主要用于:
    • 消除录音中的音频延迟 :有些录音会因为麦克风或网络传输问题导致声音和原音轨不同步。
    • 优化 AI 变声、TTS 处理 :减少因 音频滞后 导致的发音不自然或不同步问题。
    • 修复音频回声 :如果声音经过多次反射,可能会有类似 回音(Echo) 的效果,去延迟可以减少这种影响。

SoVITS 由开源社区开发 ,在 Bilibili、GitHub 社区 非常流行,特别适用于 AI VTuber、AI 歌声合成

AI 语音合成通常分为 两个主要部分

  1. 文本 → 声学特征 (文本分析 + 语音建模)
  2. 声学特征 → 波形 (波形合成)
  • 文本分析 → 解析语法,标记重音、韵律、停顿
  • 音素转换 → 将文字转换成音素(如 “hello” → /hɛˈloʊ/)
  • 语调、韵律预测 → 预测语音的起伏(高低音)
  • 时长预测 → 计算每个音素的持续时间

AI 能模仿声音,是因为 人类的语音可以被数学化描述 ,主要涉及以下几个关键参数:

参数作用
音素 (Phoneme)语音的最小单位,比如英语的 /a/, /s/
语调 (Prosody, Pitch, F0)控制说话的高低起伏
音长 (Duration)语音的时长(慢速、快速)
音色 (Timbre, Spectral Features)声音的独特性,决定声音是男、女、孩子
共振峰 (Formants)语音中的频谱特征,影响口音
语速 (Speaking Rate)说话的快慢
情感 (Emotion)控制语音的情感(开心、悲伤、愤怒等)

现代 AI 语音合成 主要使用 音频采样 + 机器学习 来获取这些参数,并用 深度神经网络 生成新的语音。

要想想做完这个之后,我要做什么,,做完这些就去百度网盘里觅食,挑出重要的东西加深印象

现代 AI 语音合成(如 GPT-4 TTS、VITS、Tacotron、WaveNet )主要依赖 深度学习信号处理 ,让计算机模仿人类的语音。

GPT接入unity中

是命名空间没有管理,所以出现了有冲突名的情况

—-搞错了,是之前DeepseekAPI里我就已经生成了一次这些json接收类,冲突了我没注意

https://i-blog.csdnimg.cn/direct/0b37c94c25e34f32a1f043c21c39822d.png

https://i-blog.csdnimg.cn/direct/8e7eced960004ac9a9c18461b2ad4966.png

类型化后,取出Json格式下的Content

https://i-blog.csdnimg.cn/direct/52f513d745c349f881f780c10472cbd1.png

使用 Newtonsoft.Json (推荐,适用于复杂JSON)

安装步骤

  1. 安装 Newtonsoft.Json (JSON.NET)

    • Unity 2021+ 版本 已自带 Newtonsoft.Json,你可以直接 using Newtonsoft.Json;
    • 如果没有,可以用 NuGet 或从 下载 DLL。

JsonUtility 只能解析 简单的 JSON 结构 ,但 OpenAI API 的返回数据是 嵌套的 JSON ,所以你需要创建多个 C# 类。

主要关心的是 choices[0].message.content ,这个字段里包含 GPT 的回复内容

https://i-blog.csdnimg.cn/direct/47b747c19c5646aaafc81dae2b47fdb3.png

https://i-blog.csdnimg.cn/direct/c5de89a08f2a47219119f8b6bb773db8.png

终于连上了

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using System.Text;

public class OpenAIClient : MonoBehaviour
{
    private string apiKey = "your-api-key";  // 你的 OpenAI API Key
    private string apiUrl = "https://api.openai.com/v1/chat/completions";

    public void SendMessageToGPT(string userMessage)
    {
        StartCoroutine(SendRequest(userMessage));
    }

    private IEnumerator SendRequest(string message)
    {
        // 构造 JSON 请求体
        string requestBody = "{\"model\": \"gpt-4\", \"messages\": [{\"role\": \"user\", \"content\": \"" + message + "\"}]}";
        byte[] requestData = Encoding.UTF8.GetBytes(requestBody);

        // 创建 UnityWebRequest
        using (UnityWebRequest request = new UnityWebRequest(apiUrl, "POST"))
        {
            request.uploadHandler = new UploadHandlerRaw(requestData);
            request.downloadHandler = new DownloadHandlerBuffer();
            request.SetRequestHeader("Content-Type", "application/json");
            request.SetRequestHeader("Authorization", "Bearer " + apiKey);

            // 发送请求并等待响应
            yield return request.SendWebRequest();

            if (request.result == UnityWebRequest.Result.Success)
            {
                Debug.Log("Response: " + request.downloadHandler.text);
            }
            else
            {
                Debug.LogError("Error: " + request.error);
            }
        }
    }
}

已经给GPT的API冲10美刀了,但问题还在(钱都冲了,今天不搞懂不行,damn)

如何关注unity store的打折信息

订阅Unity官方邮件

  • 访问 。
  • 在页面底部找到“Subscribe”或“Newsletter”选项,输入邮箱订阅,及时收到促销信息。

Unity官方社交媒体

  • 关注Unity的Twitter、Facebook等平台,官方会发布打折信息。

定期查看Asset Store

  • 经常访问Asset Store,首页通常会展示打折活动。

第三方折扣追踪网站

  • 使用第三方网站或论坛,如Reddit的Unity3D板块,获取打折信息。
  • 了解一下素材购买
  • Asset deal for unity

q,,原来野卡里可以买openAI的API

Ollama 是一个专注于提供本地化 AI 模型部署和管理的平台。它允许用户在本地环境中运行和自定义大型语言模型(LLMs),如 DeepSeek 和其他先进的 AI 模型。以下是 Ollama 的一些主要功能和用途:

  1. 本地部署 :Ollama 支持在本地计算机上部署 AI 模型,这意味着用户可以在不依赖互联网连接的情况下使用这些模型。
  2. 隐私保护 :由于模型和数据都在本地运行,Ollama 提供了更高的隐私和安全性,确保敏感信息不会被上传到云端。
  3. 自定义和扩展 :用户可以根据自己的需求对模型进行自定义和扩展,例如添加特定的知识库或调整模型参数。
  4. 多模型支持 :Ollama 支持多种 AI 模型,用户可以根据不同的任务选择最适合的模型。
  5. 开发者友好 :Ollama 提供了丰富的 API 和工具,方便开发者集成和使用这些模型。
  6. 离线使用 :通过 Ollama,用户可以在没有互联网连接的环境中继续使用 AI 模型,这对于某些特定场景(如远程工作或保密项目)非常有用。

扩展名为 Open I ,由 Kingleo 开发。它的功能是在 VS Code 编辑器内打开一个 URL。安装这个扩展后,你可以直接在 VS Code 中打开并查看网页,而不需要切换到浏览器

https://i-blog.csdnimg.cn/direct/1f3c68aea96c4c809ad8f5382e91723a.png

  1. 在 官网 :这是DeepSeek官方提供的服务,运行在DeepSeek的服务器上,用户可以直接通过网页与我交互。
  2. 通过API Key调用的我 :如果你使用自己的API Key调用我,这意味着你可能通过DeepSeek提供的API服务将我集成到你的应用程序或工具(如VSCode)中。这种情况下,请求会发送到DeepSeek的API服务器,但具体的实现方式(如响应速度、可用功能等)可能会根据API的配置和权限有所不同。
  3. 内置到VSCode的我 :如果你通过插件或扩展将我集成到VSCode中,这可能是通过API调用实现的,也可能是本地化的部署(取决于插件的实现方式)。如果是通过API调用,那么请求仍然会发送到DeepSeek的服务器;如果是本地部署,则可能运行在你的本地环境中。
  1. Top_p(Nucleus Sampling)

    • 较低的值(如 0.1 到 0.5) :生成文本会更加集中和确定,适合需要准确和一致输出的场景。
    • 较高的值(如 0.7 到 1.0) :生成文本会更加多样化和创造性,适合需要创意和变化的场景。
  2. Top_k

    • 较低的值(如 10 到 50) :生成文本会更加集中,模型只考虑概率最高的几个 token。
    • 较高的值(如 100 到 500) :生成文本会更加多样化,模型会考虑更多的 token。
  3. Frequency_penalty

    • 较低的值(如 0.0 到 0.5) :允许更多的重复,适合需要一致性和连贯性的文本。
    • 较高的值(如 1.0 到 2.0) :减少重复,使文本更加多样化,适合需要避免重复的场景。

DeepSeek API 中, Temperature 参数用于控制生成文本的随机性和创造性。这个参数的值范围通常在 0 到 2 之间,具体作用如下:

  • 低温度值(接近 0) :生成的文本会更加确定性和保守。模型倾向于选择概率最高的词,结果通常更加一致和可预测。适用于需要准确和确定性输出的场景。
  • 高温度值(接近 2) :生成的文本会更加随机和多样化。模型会更倾向于选择概率较低的词,结果可能更加创造性和不可预测。适用于需要创意和多样性的场景。

DeepSeek 的三个模型(Deepseek-Chat、Deepseek-Coder、Deepseek-Reasoner)是为了不同的应用场景和任务而设计的。每个模型都有其特定的功能和优势:

  1. Deepseek-Chat :专注于自然语言对话和交互。它适用于需要高质量对话体验的场景,如客服、虚拟助手等。
  2. Deepseek-Coder :专门用于代码生成和理解。它可以帮助开发者编写、调试和优化代码,适用于编程辅助工具和开发环境。
  3. Deepseek-Reasoner :专注于逻辑推理和问题解决。它适用于需要复杂推理和分析的任务,如数学问题求解、逻辑谜题等。

想调用GPT,,果然还是太麻烦了,,效率太低了

  • 生成式 AI

    这是一类令人兴奋的新工具,可帮助您生成新内容。您可以用它快速制作艺术作品的变体、创建角色对话等等。

  • https://i-blog.csdnimg.cn/img_convert/a74aca69d48546a90d96f58862e63a11.jpeg

    AI / ML 集成

    这些集成充当 Unity 与 Open AI 等流行 AI 系统之间的中间桥梁。通过 SDK 访问不断增加的助手和工作流程加速器目录。

  • https://i-blog.csdnimg.cn/img_convert/8db1c7c3ba633540536d3273bc33f5d7.jpeg

    行为 AI

    This is a group of tools to help you build simulated behavior for in-game non-player elements like characters and vehicles.

Deepseek回答里值得注意的一些工具,可以了解的

Unity生态系统中常用的AI工具和插件。

1.Unity自己的ML-Agents肯定是重点,用于机器学习和训练智能体。

2.第三方插件,比如A* Pathfinding Project,用于路径规划,虽然不是严格意义上的AI,但常被用于AI移动。

3.行为树插件,比如Behavior Designer,这在游戏AI中很常见。

4.对话系统,比如 SALSA和Dialogue System for Unity ,这些可能整合了AI生成对话的功能,特别是现在有生成式AI的兴起,可能会有集成ChatGPT之类的插件。

5.一些 语音识别和处理的插件,比如CROSStalk ,可能属于AI范畴。另外,Unity的 Sentience 插件,虽然不确定现在是否还在维护。可能还有第三方服务,比如OpenAI的API集成,用户自己写的插件或者Asset Store上的资源。

需要检查是否有新的插件出现,比如最近Unity和Meta的合作是否带来了一些新工具。还有,比如 Replica Voice或者Inworld AI ,这些 专注于语音生成或NPC行为的插件 。另外,像DeepSeek之类的AI创作工具是否支持Unity。

还要注意区分AI的不同应用,比如机器学习、路径寻找、自然语言处理、语音合成、行为树等,每个类别可能有不同的插件。同时,用户可能想知道是否有支持生成式AI的工具,比如集成GPT-3或 Stable Diffusion的插件

需要确认一些插件的名称是否正确,比如A* Pathfinding Project确实存在,Behavior Designer也是常用的。另外,Unity的Sentience可能已经被其他工具取代,或者是否还在活跃开发中。可能还需要提到一些 云端AI服务,如AWS或Google AI的集成 ,但用户可能更关注Unity Asset Store中的插件。

总结一下,应该分几个类别:机器学习框架、路径寻找、行为树、对话与NPC、语音处理、生成式AI集成、第三方服务集成。每个类别下列举几个主要插件,并简要说明其用途和特点。同时提醒用户注意插件的兼容性和版本, 因为Unity更新频繁,有些插件可能不支持最新版本。最后,建议用户根据具体需求选择合适的插件,并查看Asset Store的评价和文档 。


现在再填充一些关于AI相关的功能应用,了解一些前沿的知识点,看看可不可以填进对话项目里


一种很好的提问方法,问具体的信息不一定可以精准快速地回复

https://i-blog.csdnimg.cn/direct/1efd9ce0e2734dffa5fd1b8dd3a35038.png