diff --git a/lua/Trans/component/content.lua b/lua/Trans/component/content.lua
new file mode 100644
index 0000000..e86572f
--- /dev/null
+++ b/lua/Trans/component/content.lua
@@ -0,0 +1,96 @@
+local M = {}
+local type_check = require("Trans.util.debug").type_check
+M.__index = M
+M.lines = {}
+M.highlight = {}
+M.size = 0
+
+
+function M:new()
+    local content = {}
+    setmetatable(content, self)
+    return content
+end
+
+--- NOTE :highlight 格式说明:
+--- 1. 字符串
+
+
+function M:insert_items_to_line(items, opts)
+    type_check {
+        items = { items, 'table' },
+        opts = { opts, 'table', true },
+    }
+    self.size = self.size + 1 -- line数加一
+
+    local line = {
+        space = (' '):rep(opts.interval),
+        indent = opts.indent,
+        highlight = opts.highlight,
+    }
+    local highlight = {}
+
+
+    for i, item in ipairs(items) do
+        if type(item) == 'string' then
+            item = { item }
+        end
+        line[i] = item[1]
+        if item[2] then
+            highlight[i] = item[2]
+        end
+    end
+
+    self.highlight[self.size] = highlight
+    self.lines[self.size] = line
+end
+
+---遍历lines和高亮的迭代器
+---Usage:
+---     local buffer_id
+---     local lines, highlights = M:lines()
+---     vim.api.nvim_buf_set_lines(buffer_id, 0, -1, false,lines)
+---     for i, hl in ipairs(highlights) do
+---         vim.api.nvim_buf_add_highlight(buffer_id, 0, hl.name, i, hl._start, hl._end)
+---     end
+---@return table line
+---@return table highlight
+function M:lines()
+    -- NOTE 返回格式化的行,如果需要高亮,则第二个参数返回高亮
+    local lines = {}
+    local highlights = {}
+    for index = 1, #self.lines do
+        local line = ''
+        local highlight = {}
+        local l = self.lines[index]
+        local hl = self.highlight[index]
+        if l.indent then
+            line = (' '):rep(l.indent)
+        end
+        if l.highlight then
+            line = line .. table.concat(l, l.space)
+            highlight[1] = { name = l.highlight, _start = 1, _end = -1 }
+        else
+            line = line .. l[1]
+
+            if hl[1] then
+                -- WARN :可能需要设置成字符串宽度!!!
+                table.insert(highlight, { name = hl[1], _start = #line - #l[1], _end = #line })
+            end
+
+            for i = 2, #l do
+                line = line .. l.space .. l[i]
+                if hl[i] then
+                    table.insert(highlight, { name = hl[i], _start = #line - #l[i], _end = #line })
+                end
+            end
+        end
+
+        -- return line, highlights
+        lines[index] = line
+        highlights[index] = highlight
+    end
+    return lines, highlights
+end
+
+return M
diff --git a/lua/Trans/component/highlight.lua b/lua/Trans/component/highlight.lua
new file mode 100644
index 0000000..6732551
--- /dev/null
+++ b/lua/Trans/component/highlight.lua
@@ -0,0 +1,11 @@
+local M = {}
+local type_check = require("Trans.util.debug").type_check
+M.__index = M
+
+function M:new()
+    
+end
+
+
+return M
+
diff --git a/lua/Trans/component/offline/Title.lua b/lua/Trans/component/offline/Title.lua
index 19861b0..4816e0e 100644
--- a/lua/Trans/component/offline/Title.lua
+++ b/lua/Trans/component/offline/Title.lua
@@ -1,29 +1,78 @@
 local M = {}
 
 local display = require("Trans.conf.loader").loaded.conf.ui.display
--- Example:
--- local content = {
---     width = 1,
---     height = 1;
---     lines = {
---         Highlight = {
---             'first line',
---             'second line',
---         }
---     },   ---@table
+local icon = require("Trans.conf.loader").loaded.conf.ui.icon
+
+local m_field = {}
+-- {
+--   collins = 3,
+--   definition = "n. an expression of greeting",
+--   exchange = "s:hellos",
+--   oxford = 1,
+--   phonetic = "hə'ləʊ",
+--   pos = "u:97/n:3",
+--   tag = "zk gk",
+--   translation = "n. 表示问候, 惊奇或唤起注意时的用语\nint. 喂;哈罗\nn. (Hello)人名;(法)埃洛",
+--   word = "hello"
 -- }
 
 
--- local function format()
---     
--- end
+local content = {
+    lines = {
+        need_format = {
+            {}, -- line
+            {}, -- line
+            {}, -- line
+            {}, -- line
+        }
+    },
+    highlight = {
+        [2] = { -- 第几行第几个组件的高亮
+            [1] = 'highlightname',
+        },
+    }
+}
 
-M.to_content = function (field)
-    -- TODO 
-    local line = ''
-    local format = '%s  %s %s %s'
-    local content = {
-        height = 1,
+local function get_items()
+    local items = {
+        m_field.word,
+    }
+    if display.phonetic then
+        table.insert(items, '[' .. m_field.phonetic .. ']')
+    end
+
+    if display.collins_star then
+        table.insert(items, icon.star:rep(m_field.collins))
+    end
+
+    if display.oxford then
+        local item
+        if m_field.oxford and m_field.oxford == 1 then
+            item = icon.isOxford
+        else
+            item = icon.notOxford
+        end
+        table.insert(items, item)
+    end
+
+    return items
+end
+
+M.content = function(field)
+    -- TODO
+    m_field = field or {}
+    local content = {}
+
+
+    content.lines = {
+        need_format = {
+            get_items()
+        },
+        highlight = {
+            [1] = { -- 第一行
+                'Trans',
+            }
+        }
     }
     return content
 end
diff --git a/lua/Trans/component/window.lua b/lua/Trans/component/window.lua
new file mode 100644
index 0000000..bb5448f
--- /dev/null
+++ b/lua/Trans/component/window.lua
@@ -0,0 +1,12 @@
+local M = {}
+local type_check = require("Trans.util.debug").type_check
+
+
+-- vim.pretty_print(vim.lsp.util._make_floating_popup_size)
+
+local v = [=[
+    local test = {{
+    }}
+]=]
+print(v)
+return M
diff --git a/lua/Trans/conf/window.lua b/lua/Trans/conf/window.lua
index 1bad06c..c81af89 100644
--- a/lua/Trans/conf/window.lua
+++ b/lua/Trans/conf/window.lua
@@ -54,7 +54,7 @@ local get_cursor_opts = function(cursor_conf)
     return opts
 end
 
-M.get_float_opts = get_float_opts(conf.float)
+M.float_opts = get_float_opts(conf.float)
 
 M.cursor_opts = get_cursor_opts(conf.cursor)
 
diff --git a/lua/Trans/database/init.lua b/lua/Trans/database/init.lua
index 02b1405..82c2a39 100644
--- a/lua/Trans/database/init.lua
+++ b/lua/Trans/database/init.lua
@@ -18,7 +18,7 @@ local query_field = {
 }
 
 -- INFO : init database
-local path = require("Trans.conf.loader").loaded.conf.base.db_path
+local path = require("Trans.conf.loader").loaded_conf.base.db_path
 local dict = db:open(path)
 
 -- INFO :Auto Close
diff --git a/lua/Trans/database/online.lua b/lua/Trans/database/online.lua
new file mode 100644
index 0000000..e69de29
diff --git a/lua/Trans/test.lua b/lua/Trans/test.lua
new file mode 100644
index 0000000..6430e03
--- /dev/null
+++ b/lua/Trans/test.lua
@@ -0,0 +1,33 @@
+local M = {}
+
+M.test = {
+    'test1',
+    'test1',
+    'test1',
+    'test1',
+}
+
+
+function M.tmp (start, stop)
+    if start > stop then
+        return
+    end
+
+    local value = M.test[start]
+    start = start + 1
+    return function ()
+
+        return start
+    end
+end
+-- function M:tmp(index)
+-- end
+
+for v in M.tmp, 1, #M.test do
+    print(v)
+end
+
+-- for i,n in square,3,0
+-- do
+--    print(i,n)
+-- end
diff --git a/lua/Trans/util/base64.lua b/lua/Trans/util/base64.lua
new file mode 100644
index 0000000..417f8e9
--- /dev/null
+++ b/lua/Trans/util/base64.lua
@@ -0,0 +1,39 @@
+local ffi = require('ffi')
+local base64 = {}
+
+local b64 = ffi.new('unsigned const char[65]',
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")
+
+function base64.encode(str)
+    local band, bor, lsh, rsh = bit.band, bit.bor, bit.lshift, bit.rshift
+    local len = #str
+    local enc_len = 4 * math.ceil(len / 3) -- (len + 2) // 3 * 4 after Lua 5.3
+
+    local src = ffi.new('unsigned const char[?]', len+1, str)
+    local enc = ffi.new('unsigned char[?]', enc_len+1)
+
+    local i, j = 0, 0
+    while i < len-2 do
+        enc[j] = b64[band(rsh(src[i], 2), 0x3F)]
+        enc[j+1] = b64[bor(lsh(band(src[i], 0x3), 4), rsh(band(src[i+1], 0xF0), 4))]
+        enc[j+2] = b64[bor(lsh(band(src[i+1], 0xF), 2), rsh(band(src[i+2], 0xC0), 6))]
+        enc[j+3] = b64[band(src[i+2], 0x3F)]
+        i, j = i+3, j+4
+    end
+
+    if i < len then
+        enc[j] = b64[band(rsh(src[i], 2), 0x3F)]
+        if i == len-1 then
+            enc[j+1] = b64[lsh(band(src[i], 0x3), 4)]
+            enc[j+2] = 0x3D
+        else
+            enc[j+1] = b64[bor(lsh(band(src[i], 0x3), 4), rsh(band(src[i+1], 0xF0), 4))]
+            enc[j+2] = b64[lsh(band(src[i+1], 0xF), 2)]
+        end
+        enc[j+3] = 0x3D
+    end
+
+    return ffi.string(enc, enc_len)
+end
+
+return base64
diff --git a/lua/Trans/util/format.lua b/lua/Trans/util/format.lua
index a143705..9eb5ca5 100644
--- a/lua/Trans/util/format.lua
+++ b/lua/Trans/util/format.lua
@@ -5,52 +5,29 @@ local type_check = require("Trans.util.debug").type_check
 -- NOTE :中文字符及占两个字节宽,但是在lua里是3个字节长度
 -- 为了解决中文字符在lua的长度和neovim显示不一致的问题
 function string:width()
-    local wid = 0
-    local bytes = { self:byte(1, #self) }
-    local index = 1
-    while true do
-        local char = bytes[index]
-        if char > 0 and char <= 127 then -- 英文[1]
-            wid = wid + 1
-            index = index + 1
-        elseif char >= 224 and char <= 239 then -- 中文[3]
-            index = index + 3 -- 原本的宽度
-            wid = wid + 2
-            -- elseif char >= 194 and char <= 223 then -- TODO :2
-            --     width = width + 2
-            --     index = index + 2
-            -- elseif char >=240 and char <= 247 then -- TODO :4
-            --     width = width + 4
-            -- index = index + 4
-        else
-            error('unknown char len:' .. tostring(char))
-        end
-
-        if index > #bytes then
-            return wid
-        end
-    end
+    return vim.fn.strdisplaywidth(self)
 end
 
 -- 各种风格的基础宽度
 local style_width = {
-    float = require("Trans.conf.window").float.width, -- NOTE : need window parsed conf
-    cursor = require("Trans.conf.window").cursor.width,
+    -- float = require("Trans.conf.window").float.width, -- NOTE : need window parsed conf
+    -- cursor = require("Trans.conf.window").cursor.width,
+    cursor = 50
 }
 
 local s_to_b = true -- 从小到大排列
 
 local m_win_width -- 需要被格式化窗口的高度
 local m_fields -- 待格式化的字段
-local m_indent -- 每行的行首缩进
-local m_length -- 所有字段加起来的长度(不包括缩进和间隔)
+local m_tot_width -- 所有字段加起来的长度(不包括缩进和间隔)
 local m_item_width -- 每个字段的宽度
 local m_interval -- 每个字段的间隔
+local m_size -- 字段的个数
 
 local function caculate_format()
     local width = m_win_width - m_item_width[1]
     local cols = 0
-    for i = 2, #m_fields do
+    for i = 2, m_size do
         width = width - m_item_width[i] - m_interval
         if width < 0 then
             cols = i - 1
@@ -60,14 +37,20 @@ local function caculate_format()
         end
     end
 
-    return math.ceil(#m_fields / cols), cols
+    return math.ceil(m_size / cols), cols
 end
 
 local function format_to_line()
     local line = m_fields[1]
-    local space = math.floor((m_win_width - m_length) / #m_fields)
-    for i = 2, #m_fields do
-        line = line .. (' '):rep(space) .. m_fields[i]
+    if m_size == 1 then
+        --- Center Align
+        local space = math.floor((m_win_width - m_item_width[1]) / 2)
+        line = (' '):rep(space) .. line
+    else
+        local space = math.floor((m_win_width - m_tot_width) / m_size - 1)
+        for i = 2, m_size do
+            line = line .. (' '):rep(space) .. m_fields[i]
+        end
     end
     return line
 end
@@ -82,37 +65,39 @@ local function sort_tables()
     end)
 end
 
-local function format_to_multilines()
+local function format_to_multilines(rows, cols)
     local lines = {}
-    sort_tables()
 
-    --- NOTE : 计算应该格式化成多少行和列
-    local rows, cols = caculate_format()
-    local rest = #m_fields % cols
+    local rest = m_size % cols
     if rest == 0 then
         rest = cols
     end
 
     local s_width = m_item_width[1] -- 列中最宽的字符串宽度
-    -- NOTE : 第一列不需要加空格
     for i = 1, rows do
         local idx = s_to_b and rows - i + 1 or i
+        lines[idx] = {}
+
         local space = (' '):rep(s_width - m_item_width[i])
-        lines[idx] = m_fields[i] .. space -- NOTE  由大到小
+        local item = m_fields[i] .. space
+
+        lines[idx][1] = item
+        lines[idx].interval = m_interval
     end
 
+
     local index = rows + 1 -- 最宽字符的下标
-    local interval = (' '):rep(m_interval) -- 每个字符串间的间隙
 
     for j = 2, cols do -- 以列为单位遍历
         s_width = m_item_width[index]
         local stop = (j > rest and rows - 1 or rows)
         for i = 1, stop do
             local idx   = s_to_b and stop - i + 1 or i -- 当前操作的行数
-            local item  = index + i - 1 -- 当前操作的字段数
-            local space = (' '):rep(s_width - m_item_width[item]) -- 对齐空格
+            local item_idx  = index + i - 1            -- 当前操作的字段数
+            local space = (' '):rep(s_width - m_item_width[item_idx]) -- 对齐空格
+            local item = m_fields[item_idx] .. space
 
-            lines[idx] = lines[idx] .. interval .. m_fields[item] .. space -- NOTE  从大到小
+            lines[idx][j] = item -- 插入图标
         end
         index = index + stop -- 更新最宽字符的下标
     end
@@ -123,18 +108,15 @@ end
 local function formatted_lines()
     local lines = {}
     -- NOTE : 判断能否格式化成一行
-    if m_length + (#m_fields * m_indent) > m_win_width then
-        lines = format_to_multilines()
+    if m_tot_width + (m_size * m_indent) > m_win_width then
+        sort_tables()
+        --- NOTE : 计算应该格式化成多少行和列
+        local rows, cols = caculate_format()
+        lines = format_to_multilines(rows, cols)
     else
         lines[1] = format_to_line()
     end
 
-    -- NOTE :进行缩进
-    if m_indent and m_indent > 0 then
-        for i, v in ipairs(lines) do
-            lines[i] = (' '):rep(m_indent) .. v
-        end
-    end
     return lines
 end
 
@@ -155,18 +137,35 @@ M.to_lines = function(style, fields, indent)
     local item_size = {}
     for i, v in ipairs(fields) do
         width = v:width()
-        items_size[i] = width
+        item_size[i] = width
         length = length + width
     end
 
-    m_indent     = indent or 0
     m_win_width  = style_width[style] - m_indent
     m_fields     = fields
-    m_length     = length
+    m_size       = #m_fields
+    m_tot_width  = length
     m_item_width = item_size
     m_interval   = m_win_width > 50 and 6 or 4
 
     return formatted_lines()
 end
 
+---合并多个数组, 第一个数组将会被使用
+---@param ... string[] 需要被合并的数组
+---@return table res   合并后的数组
+M.extend_array = function(...)
+    local arrays = { ... }
+    local res = arrays[1]
+    local index = #res
+    for i = 2, #arrays do
+        for _, value in ipairs(arrays[i]) do
+            res[index] = value
+            index = index + 1
+        end
+    end
+    return res
+end
+
+
 return M
diff --git a/lua/Trans/util/test/format.lua b/lua/Trans/util/test/format.lua
index fe66581..62df1fe 100644
--- a/lua/Trans/util/test/format.lua
+++ b/lua/Trans/util/test/format.lua
@@ -5,30 +5,7 @@ local M = {}
 -- NOTE :中文字符及占两个字节宽,但是在lua里是3个字节长度
 -- 为了解决中文字符在lua的长度和neovim显示不一致的问题
 function string:width()
-    local width = 0
-    local bytes = { self:byte(1, #self) }
-    local index = 1
-    while true do
-        local char = bytes[index]
-        if char > 0 and char <= 127 then -- 英文[1]
-            width = width + 1
-            index = index + 1
-        elseif char >= 224 and char <= 239 then -- 中文[3]
-            index = index + 3 -- 原本的宽度
-            width = width + 2
-            -- elseif char >= 194 and char <= 223 then -- TODO :2
-            --     width = width + 2
-            --     index = index + 2
-            -- elseif char >=240 and char <= 247 then -- TODO :4
-            --     width = width + 4
-            -- index = index + 4
-        else
-            error('unknown char len:' .. tostring(char))
-        end
-        if index > #bytes then
-            return width
-        end
-    end
+    return vim.fn.strdisplaywidth(self)
 end
 
 -- 各种风格的基础宽度
@@ -40,10 +17,11 @@ local s_to_b = true -- 从小到大排列
 
 local m_fields     -- 待格式化的字段
 local m_indent     -- 每行的行首缩进
-local m_length     -- 所有字段加起来的长度(不包括缩进和间隔)
+local m_tot_width     -- 所有字段加起来的长度(不包括缩进和间隔)
 local m_interval   -- 每个字段的间隔
 local m_win_width  -- 需要被格式化窗口的高度
 local m_item_width -- 每个字段的宽度
+local m_size
 
 local function caculate_format()
     local width = m_win_width - m_item_width[1]
@@ -63,9 +41,15 @@ end
 
 local function format_to_line()
     local line = m_fields[1]
-    local space = math.floor((m_win_width - m_length) / #m_fields)
-    for i = 2, #m_fields do
-        line = line .. (' '):rep(space) .. m_fields[i]
+    if m_size == 1 then
+        --- Center Align
+        local space = math.floor((m_win_width - m_item_width[1]) / 2)
+        line = (' '):rep(space) .. line
+    else
+        local space = math.floor((m_win_width - m_tot_width) / m_size - 1)
+        for i = 2, m_size do
+            line = line .. (' '):rep(space) .. m_fields[i]
+        end
     end
     return line
 end
@@ -124,7 +108,7 @@ end
 local function get_formatted_lines()
     local lines = {}
     -- NOTE : 判断能否格式化成一行
-    local line_size = m_length + (#m_fields * m_interval)
+    local line_size = m_tot_width + (#m_fields * m_interval)
     if line_size > m_win_width then
         lines = format_to_multilines()
     else
@@ -159,20 +143,17 @@ M.to_lines = function(style, fields, indent)
     m_indent = indent or 0
     m_win_width  = style_width[style] - m_indent
     m_fields = fields
-    m_length = length
+    m_tot_width = length
     m_item_width = item_size
     m_interval = m_win_width > 50 and 6 or 4
+    m_size = #fields
 
     return get_formatted_lines()
 end
 
 local test = {
-    'ajlkasj',
-    'jklasjldajjnn测试',
-    'ljlklkjjlIi戳',
-    '测试将安得拉蓝色',
-    '戳将安塞',
-    'isjlkajsldj',
+    'isjlk测试dj',
+    '测试一下..',
 }
 
 local lines = M.to_lines('cursor', test)
@@ -187,8 +168,8 @@ local lines = M.to_lines('cursor', test)
 
 -- print('type is :' .. type(lines) .. '  size is :' .. #lines[1])
 
-for _, v in ipairs(lines) do
-    print(v)
+for _, v in ipairs(test) do
+    print(v:width())
 end
 
 -- lines = M.to_lines('cursor', {
diff --git a/lua/Trans/util/test/test.lua b/lua/Trans/util/test/test.lua
index 5c5d03f..0b99fff 100644
--- a/lua/Trans/util/test/test.lua
+++ b/lua/Trans/util/test/test.lua
@@ -1,13 +1,8 @@
-local M = {}
-
-local a = {
-    b = 'test',
+local tmp = {
+    '1111',
+    '2222',
+    '3333',
+    interval = 4,
 }
 
-local c = a
-c.b = 'notest'
-
-
-
-print(a.b)
-return M
+print(table.concat(tmp, (' '):rep(tmp.interval)))