程式環境都會用colab 來執行程式,如果要在其他環境執行,請自行修改哦
colab 事前準備:設定專案和 API 金鑰
載入gemini
#pip install -q -U google-generativeai
import google.generativeai as genai
API 金鑰
from google.colab import userdata
API_KEY=userdata.get('GOOGLE_API_KEY')
#genai.configure(api_key="YOUR_API_KEY")
# Configure the client library by providing your API key.
genai.configure(api_key=API_KEY)
使用 Gemini API 擷取結構化資料,從故事中擷取角色、關係、事物和地點的清單。
import pathlib
import textwrap
import google.generativeai as genai
from IPython.display import display
from IPython.display import Markdown
from google.api_core import retry
def to_markdown(text):
text = text.replace('•', ' *')
return Markdown(textwrap.indent(text, '> ', predicate=lambda _: True))
new_story = False
if new_story:
model = genai.GenerativeModel(model_name='models/gemini-1.5-pro-latest')
response = model.generate_content("""
寫一個關於一個背著魔法背包的女孩、她的家人以及在
至少還有一個角色。確保每個人都有名字。別忘了
描述背包中的物品以及每個人和所有物品的位置
開始和結束。""", request_options={'retry': retry.Retry()})
story = response.text
print(response.candidates[0].citation_metadata)
else:
story = """在古色古香的柳溪鎮,坐落在起伏的山巒和低語的柳樹之中,住著一個名叫安雅的年輕女孩。當她走出簡陋小屋的吱吱作響的木門時,她的心因興奮和期待而漏跳了一拍。今天是她上學的第一天,她迫不及待地想炫耀自己的寶貝——一個神奇的背包。 \n\n這個背包是她祖母傳給她的,可不是普通的書包。它柔軟的翠綠色織物閃爍著空靈的光芒,它的皮帶上藏著只有安雅知道的秘密。其寬敞的內部是一個迷人的世界,充滿了奇蹟,這些奇蹟將激發她的想像並永遠改變她的生活。的擁抱向她告別。 “記住,親愛的,”她母親低聲說道,“明智地、永遠地使用你的魔法。”她的父親補充說:「永遠尋求知識,讓背包成為你值得信賴的伴侶。」\n\n安雅腳步輕快,向鎮上唯一的校舍走去。在路上,她經過了她最好的朋友塞繆爾,一個充滿好奇心、喜歡冒險、帶著頑皮笑容的男孩。 「嘿,安雅,」他喊道。 「我可以看看你的背包嗎?」\n\n安雅猶豫了一會兒,然後拉開拉鍊,露出裡面的東西。塞繆爾向裡面看去,驚訝地睜大了眼睛。在那裡,在鉛筆和筆記本中間,有一把閃閃發光的劍、一本古老的咒語書、一個始終指向北方的小指南針,以及一把可以打開任何鎖的神奇鑰匙。背包的奇蹟,並承諾以確保其秘密的安全。當他們接近校舍時,安雅注意到一群年紀較大的孩子擠在一起,臉上充滿了恐懼。好奇心戰勝了她,她小心翼翼地靠近。她問道。 「森林裡有個怪物。」他結結巴巴地說。 「它一直在恐嚇小鎮,攻擊動物甚至人類。」\n\n安雅的心沉了下去。柳溪鎮小而寧靜,一想到怪物就讓她背脊發涼。她知道她必須做點什麼來保護她的家人和朋友。她眼中閃爍著堅定的光芒,轉向驚恐的同伴。 「別擔心,」她聲音平穩地說。 「我會處理的。」\n\n塞繆爾緊隨其後,安雅冒險走進了森林的陰暗深處。當她經過時,樹木似乎在低聲訴說著秘密,灌木叢中看不見的生物沙沙作響。隨著他們向森林深處走去,空氣變得凝重,腳下的地面都在顫抖。獸。這個生物咆哮著,雷鳴般的聲音震動了森林的核心。她從劍鞘中拔出劍,向怪物衝去。劍刃在陽光下閃閃發光,當它擊中怪物的皮毛時,爆發出耀眼的光芒,將一切都籠罩在光芒中。的水晶。安雅用背包的魔法打敗了這個生物,證明即使是最小的物體也能擁有最強大的力量。 \n\n當她和塞繆爾回到小鎮時,他們受到了英雄般的歡迎。柳溪人歡欣鼓舞,背著魔法背包的女孩安雅的傳說也世代相傳。因此,安雅繼續她的冒險,利用背包的奇蹟,一步一步神奇地讓世界變得更美好。"""
to_markdown(story)
回答
在古色古香的柳溪鎮,坐落在起伏的山巒和低語的柳樹之中,住著一個名叫安雅的年輕女孩。當她走出簡陋小屋的吱吱作響的木門時,她的心因興奮和期待而漏跳了一拍。今天是她上學的第一天,她迫不及待地想炫耀自己的寶貝——一個神奇的背包。
這個背包是她祖母傳給她的,可不是普通的書包。它柔軟的翠綠色織物閃爍著空靈的光芒,它的皮帶上藏著只有安雅知道的秘密。其寬敞的內部是一個迷人的世界,充滿了奇蹟,這些奇蹟將激發她的想像並永遠改變她的生活。的擁抱向她告別。 “記住,親愛的,”她母親低聲說道,“明智地、永遠地使用你的魔法。”她的父親補充說:「永遠尋求知識,讓背包成為你值得信賴的伴侶。」
安雅腳步輕快,向鎮上唯一的校舍走去。在路上,她經過了她最好的朋友塞繆爾,一個充滿好奇心、喜歡冒險、帶著頑皮笑容的男孩。 「嘿,安雅,」他喊道。 「我可以看看你的背包嗎?」
安雅猶豫了一會兒,然後拉開拉鍊,露出裡面的東西。塞繆爾向裡面看去,驚訝地睜大了眼睛。在那裡,在鉛筆和筆記本中間,有一把閃閃發光的劍、一本古老的咒語書、一個始終指向北方的小指南針,以及一把可以打開任何鎖的神奇鑰匙。背包的奇蹟,並承諾以確保其秘密的安全。當他們接近校舍時,安雅注意到一群年紀較大的孩子擠在一起,臉上充滿了恐懼。好奇心戰勝了她,她小心翼翼地靠近。她問道。 「森林裡有個怪物。」他結結巴巴地說。 「它一直在恐嚇小鎮,攻擊動物甚至人類。」
安雅的心沉了下去。柳溪鎮小而寧靜,一想到怪物就讓她背脊發涼。她知道她必須做點什麼來保護她的家人和朋友。她眼中閃爍著堅定的光芒,轉向驚恐的同伴。 「別擔心,」她聲音平穩地說。 「我會處理的。」
塞繆爾緊隨其後,安雅冒險走進了森林的陰暗深處。當她經過時,樹木似乎在低聲訴說著秘密,灌木叢中看不見的生物沙沙作響。隨著他們向森林深處走去,空氣變得凝重,腳下的地面都在顫抖。獸。這個生物咆哮著,雷鳴般的聲音震動了森林的核心。她從劍鞘中拔出劍,向怪物衝去。劍刃在陽光下閃閃發光,當它擊中怪物的皮毛時,爆發出耀眼的光芒,將一切都籠罩在光芒中。的水晶。安雅用背包的魔法打敗了這個生物,證明即使是最小的物體也能擁有最強大的力量。
當她和塞繆爾回到小鎮時,他們受到了英雄般的歡迎。柳溪人歡欣鼓舞,背著魔法背包的女孩安雅的傳說也世代相傳。因此,安雅繼續她的冒險,利用背包的奇蹟,一步一步神奇地讓世界變得更美好。
大型語言模型是強大的多工處理工具。通常只要向 Gemini 問句即可,沒問題。
Gemini API 不提供 JSON 模式,因此以這種方式產生資料結構時,請注意以下事項:
使用簡單的自然語言提示,搭配以文字呈現的結構定義。這未經最佳化:
model = genai.GenerativeModel(
model_name='models/gemini-1.5-pro-latest')
response = model.generate_content(
textwrap.dedent("""\
請使用以下模式傳回描述此故事中的人物、地點、事物和關係的 JSON:
{"people": list[PERSON], "places":list[PLACE], "things":list[THING], "relationships": list[RELATIONSHIP]}
str 用繁體中文描述。例如:"name": "柳溪鎮"
PERSON = {"name": str, "description": str, "start_place_name": str, "end_place_name": str}
PLACE = {"name": str, "description": str}
THING = {"name": str, "description": str, "start_place_name": str, "end_place_name": str}
RELATIONSHIP = {"person_1_name": str, "person_2_name": str, "relationship": str}
所有欄位均為必填欄位。
重要提示:僅傳回一段有效的 JSON 文字。
故事是這樣的:
""") + story,
generation_config={'response_mime_type':'application/json'}
)
response.text
回答
{"people": [{"name": "安雅", "description": "一個住在柳溪鎮的年輕女孩,在上學第一天,帶著一個神奇的背包。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}, {"name": "安雅的祖母", "description": "送給安雅一個神奇背包的人。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}, {"name": "安雅的母親", "description": "提醒安雅明智地使用魔法的人。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}, {"name": "安雅的父親", "description": "告訴安雅要永遠追求知識的人。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}, {"name": "塞繆爾", "description": "安雅最好的朋友,一個充滿好奇心、喜歡冒險的男孩。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}, {"name": "一個年紀較大的孩子", "description": "告訴安雅森林裡有怪物的人。", "start_place_name": "柳溪鎮", "end_place_name": "柳溪鎮"}], "places": [{"name": "柳溪鎮", "description": "一個坐落在起伏的山巒和低語的柳樹之中的古色古香的小鎮。"}, {"name": "安雅簡陋的小屋", "description": "安雅在柳溪鎮的家。"}, {"name": "學校", "description": "柳溪鎮唯一的校舍。"}, {"name": "森林", "description": "一個黑暗而可怕的地方,怪物就住在那裡。"}], "things": [{"name": "神奇的背包", "description": "一個柔軟的翠綠色織物背包,裡面裝滿了神奇的物品,可以激發想像力。", "start_place_name": "安雅簡陋的小屋", "end_place_name": "森林"}, {"name": "閃閃發光的劍", "description": "背包裡用來打敗怪物的武器。", "start_place_name": "神奇的背包", "end_place_name": "森林"}, {"name": "古老的咒語書", "description": "背包裡裝滿了魔法和咒語的書。", "start_place_name": "神奇的背包", "end_place_name": "神奇的背包"}, {"name": "小指南針", "description": "背包裡始終指向北方的小指南針。", "start_place_name": "神奇的背包", "end_place_name": "神奇的背包"}, {"name": "神奇的鑰匙", "description": "背包裡可以打開任何鎖的鑰匙。", "start_place_name": "神奇的背包", "end_place_name": "神奇的背包"}, {"name": "鉛筆", "description": "安雅背包裡的學習用品。", "start_place_name": "神奇的背包", "end_place_name": "神奇的背包"}, {"name": "筆記本", "description": "安雅背包裡的學習用品。", "start_place_name": "神奇的背包", "end_place_name": "神奇的背包"}], "relationships": [{"person_1_name": "安雅", "person_2_name": "塞繆爾", "relationship": "最好的朋友"}, {"person_1_name": "安雅", "person_2_name": "安雅的祖母", "relationship": "孫女"}, {"person_1_name": "安雅", "person_2_name": "安雅的母親", "relationship": "女兒"}, {"person_1_name": "安雅", "person_2_name": "安雅的父親", "relationship": "女兒"}]}
import json
print(json.dumps(json.loads(response.text), indent=4))
回答
{
"people": [
{
"name": "\u5b89\u96c5",
"description": "\u4e00\u500b\u4f4f\u5728\u67f3\u6eaa\u93ae\u7684\u5e74\u8f15\u5973\u5b69\uff0c\u5728\u4e0a\u5b78\u7b2c\u4e00\u5929\uff0c\u5e36\u8457\u4e00\u500b\u795e\u5947\u7684\u80cc\u5305\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
},
{
"name": "\u5b89\u96c5\u7684\u7956\u6bcd",
"description": "\u9001\u7d66\u5b89\u96c5\u4e00\u500b\u795e\u5947\u80cc\u5305\u7684\u4eba\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
},
{
"name": "\u5b89\u96c5\u7684\u6bcd\u89aa",
"description": "\u63d0\u9192\u5b89\u96c5\u660e\u667a\u5730\u4f7f\u7528\u9b54\u6cd5\u7684\u4eba\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
},
{
"name": "\u5b89\u96c5\u7684\u7236\u89aa",
"description": "\u544a\u8a34\u5b89\u96c5\u8981\u6c38\u9060\u8ffd\u6c42\u77e5\u8b58\u7684\u4eba\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
},
{
"name": "\u585e\u7e46\u723e",
"description": "\u5b89\u96c5\u6700\u597d\u7684\u670b\u53cb\uff0c\u4e00\u500b\u5145\u6eff\u597d\u5947\u5fc3\u3001\u559c\u6b61\u5192\u96aa\u7684\u7537\u5b69\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
},
{
"name": "\u4e00\u500b\u5e74\u7d00\u8f03\u5927\u7684\u5b69\u5b50",
"description": "\u544a\u8a34\u5b89\u96c5\u68ee\u6797\u88e1\u6709\u602a\u7269\u7684\u4eba\u3002",
"start_place_name": "\u67f3\u6eaa\u93ae",
"end_place_name": "\u67f3\u6eaa\u93ae"
}
],
"places": [
{
"name": "\u67f3\u6eaa\u93ae",
"description": "\u4e00\u500b\u5750\u843d\u5728\u8d77\u4f0f\u7684\u5c71\u5dd2\u548c\u4f4e\u8a9e\u7684\u67f3\u6a39\u4e4b\u4e2d\u7684\u53e4\u8272\u53e4\u9999\u7684\u5c0f\u93ae\u3002"
},
{
"name": "\u5b89\u96c5\u7c21\u964b\u7684\u5c0f\u5c4b",
"description": "\u5b89\u96c5\u5728\u67f3\u6eaa\u93ae\u7684\u5bb6\u3002"
},
{
"name": "\u5b78\u6821",
"description": "\u67f3\u6eaa\u93ae\u552f\u4e00\u7684\u6821\u820d\u3002"
},
{
"name": "\u68ee\u6797",
"description": "\u4e00\u500b\u9ed1\u6697\u800c\u53ef\u6015\u7684\u5730\u65b9\uff0c\u602a\u7269\u5c31\u4f4f\u5728\u90a3\u88e1\u3002"
}
],
"things": [
{
"name": "\u795e\u5947\u7684\u80cc\u5305",
"description": "\u4e00\u500b\u67d4\u8edf\u7684\u7fe0\u7da0\u8272\u7e54\u7269\u80cc\u5305\uff0c\u88e1\u9762\u88dd\u6eff\u4e86\u795e\u5947\u7684\u7269\u54c1\uff0c\u53ef\u4ee5\u6fc0\u767c\u60f3\u50cf\u529b\u3002",
"start_place_name": "\u5b89\u96c5\u7c21\u964b\u7684\u5c0f\u5c4b",
"end_place_name": "\u68ee\u6797"
},
{
"name": "\u9583\u9583\u767c\u5149\u7684\u528d",
"description": "\u80cc\u5305\u88e1\u7528\u4f86\u6253\u6557\u602a\u7269\u7684\u6b66\u5668\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u68ee\u6797"
},
{
"name": "\u53e4\u8001\u7684\u5492\u8a9e\u66f8",
"description": "\u80cc\u5305\u88e1\u88dd\u6eff\u4e86\u9b54\u6cd5\u548c\u5492\u8a9e\u7684\u66f8\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u795e\u5947\u7684\u80cc\u5305"
},
{
"name": "\u5c0f\u6307\u5357\u91dd",
"description": "\u80cc\u5305\u88e1\u59cb\u7d42\u6307\u5411\u5317\u65b9\u7684\u5c0f\u6307\u5357\u91dd\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u795e\u5947\u7684\u80cc\u5305"
},
{
"name": "\u795e\u5947\u7684\u9470\u5319",
"description": "\u80cc\u5305\u88e1\u53ef\u4ee5\u6253\u958b\u4efb\u4f55\u9396\u7684\u9470\u5319\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u795e\u5947\u7684\u80cc\u5305"
},
{
"name": "\u925b\u7b46",
"description": "\u5b89\u96c5\u80cc\u5305\u88e1\u7684\u5b78\u7fd2\u7528\u54c1\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u795e\u5947\u7684\u80cc\u5305"
},
{
"name": "\u7b46\u8a18\u672c",
"description": "\u5b89\u96c5\u80cc\u5305\u88e1\u7684\u5b78\u7fd2\u7528\u54c1\u3002",
"start_place_name": "\u795e\u5947\u7684\u80cc\u5305",
"end_place_name": "\u795e\u5947\u7684\u80cc\u5305"
}
],
"relationships": [
{
"person_1_name": "\u5b89\u96c5",
"person_2_name": "\u585e\u7e46\u723e",
"relationship": "\u6700\u597d\u7684\u670b\u53cb"
},
{
"person_1_name": "\u5b89\u96c5",
"person_2_name": "\u5b89\u96c5\u7684\u7956\u6bcd",
"relationship": "\u5b6b\u5973"
},
{
"person_1_name": "\u5b89\u96c5",
"person_2_name": "\u5b89\u96c5\u7684\u6bcd\u89aa",
"relationship": "\u5973\u5152"
},
{
"person_1_name": "\u5b89\u96c5",
"person_2_name": "\u5b89\u96c5\u7684\u7236\u89aa",
"relationship": "\u5973\u5152"
}
]
}
使用函式呼叫函式及相關參數時,即可向 API 說明 做為 genai.protos.FunctionDeclaration
將 person 定義為包含字串欄位 name、description、start_place_name、end_place_name 的物件。
person = genai.protos.Schema(
type = genai.protos.Type.OBJECT,
properties = {
'name': genai.protos.Schema(type=genai.protos.Type.STRING),
'description': genai.protos.Schema(type=genai.protos.Type.STRING),
'start_place_name': genai.protos.Schema(type=genai.protos.Type.STRING),
'end_place_name': genai.protos.Schema(type=genai.protos.Type.STRING)
},
required=['name', 'description', 'start_place_name', 'end_place_name']
)
將使用者定義為 person 物件的 ARRAY:
people = genai.protos.Schema(
type=genai.protos.Type.ARRAY,
items=person
)
擷取的每個實體執行相同操作
place = genai.protos.Schema(
type = genai.protos.Type.OBJECT,
properties = {
'name': genai.protos.Schema(type=genai.protos.Type.STRING),
'description': genai.protos.Schema(type=genai.protos.Type.STRING),
}
)
places = genai.protos.Schema(
type=genai.protos.Type.ARRAY,
items=place
)
thing = genai.protos.Schema(
type = genai.protos.Type.OBJECT,
properties = {
'name': genai.protos.Schema(type=genai.protos.Type.STRING),
'description': genai.protos.Schema(type=genai.protos.Type.STRING),
}
)
things = genai.protos.Schema(
type=genai.protos.Type.ARRAY,
items=thing
)
relationship = genai.protos.Schema(
type = genai.protos.Type.OBJECT,
properties = {
'person_1_name': genai.protos.Schema(type=genai.protos.Type.STRING),
'person_2_name': genai.protos.Schema(type=genai.protos.Type.STRING),
'relationship': genai.protos.Schema(type=genai.protos.Type.STRING),
}
)
relationships = genai.protos.Schema(
type=genai.protos.Type.ARRAY,
items=relationship
)
place = genai.protos.Schema(
type = genai.protos.Type.OBJECT,
properties = {
'name': genai.protos.Schema(type=genai.protos.Type.STRING),
'description': genai.protos.Schema(type=genai.protos.Type.STRING),
}
)
places = genai.protos.Schema(
type=genai.protos.Type.ARRAY,
items=place
)
add_to_database = genai.protos.FunctionDeclaration(
name="add_to_database",
description=textwrap.dedent("""\
將實體新增至資料庫。
"""),
parameters=genai.protos.Schema(
type=genai.protos.Type.OBJECT,
properties = {
'people': people,
'places': places,
'things': things,
'relationships': relationships
}
)
)
呼叫 API
model = genai.GenerativeModel(
model_name='models/gemini-1.5-pro-latest',
tools = [add_to_database])
呼叫 API 時,SDK 會將工具與提示一併傳送,模型應呼叫您定義的函式
result = model.generate_content(f"""
Please add the people, places, things, and relationships from this story to the database:
{story}
""",
# Force a function call
tool_config={'function_calling_config':'ANY'})
沒有可剖析的文字
'text' in result.candidates[0].content.parts[0]
False
產生「是」資料結構
'function_call' in result.candidates[0].content.parts[0]
Ture
genai.protos.FunctionCall 類別
fc = result.candidates[0].content.parts[0].function_call
print(type(fc))
<class 'google.ai.generativelanguage_v1beta.types.content.FunctionCall'>
print(json.dumps(type(fc).to_dict(fc), indent=4))
回答
{
"name": "add_to_database",
"args": {
"people": [
{
"name": "Anya",
"end_place_name": "Willow Creek",
"description": "A young girl who is the story's protagonist. She is brave, curious, and kind. She uses her magic backpack to help her family and friends.",
"start_place_name": "Willow Creek"
},
{
"start_place_name": "Willow Creek",
"end_place_name": "Willow Creek",
"name": "Samuel",
"description": "A boy who is Anya's best friend. He is curious, adventurous, and has a mischievous smile."
},
{
"name": "Anya's Mother",
"description": "Anya's mother. She is loving and supportive.",
"end_place_name": "Willow Creek",
"start_place_name": "Willow Creek"
},
{
"name": "Anya's Father",
"description": "Anya's father. He is wise and encouraging.",
"start_place_name": "Willow Creek",
"end_place_name": "Willow Creek"
}
],
"places": [
{
"name": "Willow Creek",
"description": "A quaint town nestled amidst rolling hills and whispering willow trees."
},
{
"description": "Anya's humble abode.",
"name": "Anya's Cottage"
},
{
"name": "Willow Creek Schoolhouse",
"description": "The only schoolhouse in Willow Creek."
},
{
"description": "A dark and mysterious place where a monster resides.",
"name": "Forest"
}
],
"things": [
{
"description": "A magical bag passed down to Anya from her grandmother. It contains wondrous items that can change her life.",
"name": "Magic Backpack"
},
{
"name": "Sword",
"description": "A sword that Anya uses to defeat the monster."
},
{
"name": "Book of Spells",
"description": "An ancient book of spells that Anya keeps in her backpack."
},
{
"description": "A small compass that always points north. Anya carries it in her backpack.",
"name": "Compass"
},
{
"name": "Magic Key",
"description": "A key that can open any lock. Anya keeps it in her backpack."
},
{
"name": "Pencils",
"description": "Pencils that Anya carries in her backpack for school."
},
{
"description": "Notebooks that Anya carries in her backpack for school.",
"name": "Notebooks"
},
{
"description": "A terrifying creature that lives in the forest and terrorizes the town.",
"name": "Monster"
}
],
"relationships": [
{
"relationship": "best friends",
"person_2_name": "Samuel",
"person_1_name": "Anya"
},
{
"person_2_name": "Anya's Mother",
"person_1_name": "Anya",
"relationship": "daughter"
},
{
"person_1_name": "Anya",
"person_2_name": "Anya's Father",
"relationship": "daughter"
}
]
}
}