diff options
Diffstat (limited to 'core/lua')
-rw-r--r-- | core/lua/astal-dev-1.rockspec | 31 | ||||
-rw-r--r-- | core/lua/astal/application.lua | 94 | ||||
-rw-r--r-- | core/lua/astal/binding.lua | 71 | ||||
-rw-r--r-- | core/lua/astal/file.lua | 45 | ||||
-rw-r--r-- | core/lua/astal/init.lua | 41 | ||||
-rw-r--r-- | core/lua/astal/process.lua | 78 | ||||
-rw-r--r-- | core/lua/astal/time.lua | 27 | ||||
-rw-r--r-- | core/lua/astal/variable.lua | 276 | ||||
-rw-r--r-- | core/lua/astal/widget.lua | 322 | ||||
-rw-r--r-- | core/lua/stylua.toml | 3 |
10 files changed, 0 insertions, 988 deletions
diff --git a/core/lua/astal-dev-1.rockspec b/core/lua/astal-dev-1.rockspec deleted file mode 100644 index 9a41fd1..0000000 --- a/core/lua/astal-dev-1.rockspec +++ /dev/null @@ -1,31 +0,0 @@ -package = "astal" -version = "dev-1" - -source = { - url = "git+https://github.com/aylur/astal", -} - -description = { - summary = "lua bindings for libastal.", - homepage = "https://aylur.github.io/astal/", - license = "GPL-3", -} - -dependencies = { - "lua >= 5.1, < 5.4", - "lgi >= 0.9.2", -} - -build = { - type = "builtin", - modules = { - ["astal.application"] = "astal/application.lua", - ["astal.binding"] = "astal/binding.lua", - ["astal.init"] = "astal/init.lua", - ["astal.process"] = "astal/process.lua", - ["astal.time"] = "astal/time.lua", - ["astal.variable"] = "astal/variable.lua", - ["astal.widget"] = "astal/widget.lua", - ["astal.file"] = "astal/file.lua", - }, -} diff --git a/core/lua/astal/application.lua b/core/lua/astal/application.lua deleted file mode 100644 index 663a457..0000000 --- a/core/lua/astal/application.lua +++ /dev/null @@ -1,94 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") - -local AstalLua = Astal.Application:derive("AstalLua") -local request_handler - -function AstalLua:do_request(msg, conn) - if type(request_handler) == "function" then - request_handler(msg, function(response) - Astal.write_sock(conn, tostring(response), function(_, res) - Astal.write_sock_finish(res) - end) - end) - else - Astal.Application.do_request(self, msg, conn) - end -end - -function AstalLua:quit(code) - Astal.Application.quit(self) - os.exit(code) -end - -local app = AstalLua() - ----@class StartConfig ----@field icons? string ----@field instance_name? string ----@field gtk_theme? string ----@field icon_theme? string ----@field cursor_theme? string ----@field css? string ----@field hold? boolean ----@field request_handler? fun(msg: string, response: fun(res: any)) ----@field main? fun(...): unknown ----@field client? fun(message: fun(msg: string): string, ...): unknown - ----@param config StartConfig | nil -function Astal.Application:start(config) - if config == nil then - config = {} - end - - if config.client == nil then - config.client = function() - print('Astal instance "' .. app.instance_name .. '" is already running') - os.exit(1) - end - end - - if config.hold == nil then - config.hold = true - end - - request_handler = config.request_handler - - if config.css then - self:apply_css(config.css) - end - if config.icons then - self:add_icons(config.icons) - end - if config.instance_name then - self.instance_name = config.instance_name - end - if config.gtk_theme then - self.gtk_theme = config.gtk_theme - end - if config.icon_theme then - self.icon_theme = config.icon_theme - end - if config.cursor_theme then - self.cursor_theme = config.cursor_theme - end - - app.on_activate = function() - if type(config.main) == "function" then - config.main(table.unpack(arg)) - end - if config.hold then - self:hold() - end - end - - if not app:acquire_socket() then - return config.client(function(msg) - return Astal.Application.send_message(self.instance_name, msg) - end, table.unpack(arg)) - end - - self:run(nil) -end - -return app diff --git a/core/lua/astal/binding.lua b/core/lua/astal/binding.lua deleted file mode 100644 index ba1e6e4..0000000 --- a/core/lua/astal/binding.lua +++ /dev/null @@ -1,71 +0,0 @@ -local lgi = require("lgi") -local GObject = lgi.require("GObject", "2.0") - ----@class Binding ----@field emitter table|Variable ----@field property? string ----@field transformFn function -local Binding = {} - ----@param emitter table ----@param property? string ----@return Binding -function Binding.new(emitter, property) - return setmetatable({ - emitter = emitter, - property = property, - transformFn = function(v) - return v - end, - }, Binding) -end - -function Binding:__tostring() - local str = "Binding<" .. tostring(self.emitter) - if self.property ~= nil then - str = str .. ", " .. self.property - end - return str .. ">" -end - -function Binding:get() - if self.property ~= nil and GObject.Object:is_type_of(self.emitter) then - return self.transformFn(self.emitter[self.property]) - end - if type(self.emitter.get) == "function" then - return self.transformFn(self.emitter:get()) - end - error("can not get: Not a GObject or a Variable " + self) -end - ----@param transform fun(value: any): any ----@return Binding -function Binding:as(transform) - local b = Binding.new(self.emitter, self.property) - b.transformFn = function(v) - return transform(self.transformFn(v)) - end - return b -end - ----@param callback fun(value: any) ----@return function -function Binding:subscribe(callback) - if self.property ~= nil and GObject.Object:is_type_of(self.emitter) then - local id = self.emitter.on_notify:connect(function() - callback(self:get()) - end, self.property, false) - return function() - GObject.signal_handler_disconnect(self.emitter, id) - end - end - if type(self.emitter.subscribe) == "function" then - return self.emitter:subscribe(function() - callback(self:get()) - end) - end - error("can not subscribe: Not a GObject or a Variable " + self) -end - -Binding.__index = Binding -return Binding diff --git a/core/lua/astal/file.lua b/core/lua/astal/file.lua deleted file mode 100644 index ca5a592..0000000 --- a/core/lua/astal/file.lua +++ /dev/null @@ -1,45 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") -local GObject = lgi.require("GObject", "2.0") - -local M = {} - ----@param path string ----@return string -function M.read_file(path) - return Astal.read_file(path) -end - ----@param path string ----@param callback fun(content: string, err: string): nil -function M.read_file_async(path, callback) - Astal.read_file_async(path, function(_, res) - local content, err = Astal.read_file_finish(res) - callback(content, err) - end) -end - ----@param path string ----@param content string -function M.write_file(path, content) - Astal.write_file(path, content) -end - ----@param path string ----@param content string ----@param callback? fun(err: string): nil -function M.write_file_async(path, content, callback) - Astal.write_file_async(path, content, function(_, res) - if type(callback) == "function" then - callback(Astal.write_file_finish(res)) - end - end) -end - ----@param path string ----@param callback fun(file: string, event: integer): nil -function M.monitor_file(path, callback) - return Astal.monitor_file(path, GObject.Closure(callback)) -end - -return M diff --git a/core/lua/astal/init.lua b/core/lua/astal/init.lua deleted file mode 100644 index f56c3f5..0000000 --- a/core/lua/astal/init.lua +++ /dev/null @@ -1,41 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") -local Gtk = lgi.require("Gtk", "3.0") -local Gdk = lgi.require("Gdk", "3.0") -local GObject = lgi.require("GObject", "2.0") -local Widget = require("astal.widget") -local Variable = require("astal.variable") -local Binding = require("astal.binding") -local App = require("astal.application") -local Process = require("astal.process") -local Time = require("astal.time") -local File = require("astal.file") - -return { - App = App, - Variable = Variable, - Widget = Widget, - bind = Binding.new, - - interval = Time.interval, - timeout = Time.timeout, - idle = Time.idle, - - subprocess = Process.subprocess, - exec = Process.exec, - exec_async = Process.exec_async, - - read_file = File.read_file, - read_file_async = File.read_file_async, - write_file = File.write_file, - write_file_async = File.write_file_async, - monitor_file = File.monitor_file, - - Astal = Astal, - Gtk = Gtk, - Gdk = Gdk, - GObject = GObject, - GLib = lgi.require("GLib", "2.0"), - Gio = lgi.require("Gio", "2.0"), - require = lgi.require, -} diff --git a/core/lua/astal/process.lua b/core/lua/astal/process.lua deleted file mode 100644 index 62360b3..0000000 --- a/core/lua/astal/process.lua +++ /dev/null @@ -1,78 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") - -local M = {} - ----@param commandline string | string[] ----@param on_stdout? fun(out: string): nil ----@param on_stderr? fun(err: string): nil ----@return { kill: function } | nil proc -function M.subprocess(commandline, on_stdout, on_stderr) - if on_stdout == nil then - on_stdout = function(out) - io.stdout:write(tostring(out) .. "\n") - end - end - - if on_stderr == nil then - on_stderr = function(err) - io.stderr:write(tostring(err) .. "\n") - end - end - - local proc, err - if type(commandline) == "table" then - proc, err = Astal.Process.subprocessv(commandline) - else - proc, err = Astal.Process.subprocess(commandline) - end - if err ~= nil then - err(err) - return nil - end - proc.on_stdout = function(_, stdoud) - on_stdout(stdoud) - end - proc.on_stderr = function(_, stderr) - on_stderr(stderr) - end - return proc -end - ----@param commandline string | string[] ----@return string, string -function M.exec(commandline) - if type(commandline) == "table" then - return Astal.Process.execv(commandline) - else - return Astal.Process.exec(commandline) - end -end - ----@param commandline string | string[] ----@param callback? fun(out: string, err: string): nil -function M.exec_async(commandline, callback) - if callback == nil then - callback = function(out, err) - if err ~= nil then - io.stdout:write(tostring(out) .. "\n") - else - io.stderr:write(tostring(err) .. "\n") - end - end - end - - if type(commandline) == "table" then - Astal.Process.exec_asyncv(commandline, function(_, res) - local out, err = Astal.Process.exec_asyncv_finish(res) - callback(out, err) - end) - else - Astal.Process.exec_async(commandline, function(_, res) - local out, err = Astal.Process.exec_finish(res) - callback(out, err) - end) - end -end - -return M diff --git a/core/lua/astal/time.lua b/core/lua/astal/time.lua deleted file mode 100644 index f4e2b81..0000000 --- a/core/lua/astal/time.lua +++ /dev/null @@ -1,27 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") -local GObject = lgi.require("GObject", "2.0") - -local M = {} - ----@param interval number ----@param fn function ----@return { cancel: function, on_now: function } -function M.interval(interval, fn) - return Astal.Time.interval(interval, GObject.Closure(fn)) -end - ----@param timeout number ----@param fn function ----@return { cancel: function, on_now: function } -function M.timeout(timeout, fn) - return Astal.Time.timeout(timeout, GObject.Closure(fn)) -end - ----@param fn function ----@return { cancel: function, on_now: function } -function M.idle(fn) - return Astal.Time.idle(GObject.Closure(fn)) -end - -return M diff --git a/core/lua/astal/variable.lua b/core/lua/astal/variable.lua deleted file mode 100644 index 662eee7..0000000 --- a/core/lua/astal/variable.lua +++ /dev/null @@ -1,276 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") -local GObject = lgi.require("GObject", "2.0") -local Binding = require("astal.binding") -local Time = require("astal.time") -local Process = require("astal.process") - ----@class Variable ----@field private variable table ----@field private err_handler? function ----@field private _value any ----@field private _poll? table ----@field private _watch? table ----@field private poll_interval number ----@field private poll_exec? string[] | string ----@field private poll_transform? fun(next: any, prev: any): any ----@field private poll_fn? function ----@field private watch_transform? fun(next: any, prev: any): any ----@field private watch_exec? string[] | string -local Variable = {} -Variable.__index = Variable - ----@param value any ----@return Variable -function Variable.new(value) - local v = Astal.VariableBase() - local variable = setmetatable({ - variable = v, - _value = value, - }, Variable) - v.on_dropped = function() - variable:stop_watch() - variable:stop_watch() - end - v.on_error = function(_, err) - if variable.err_handler then - variable.err_handler(err) - end - end - return variable -end - ----@param transform function ----@return Binding -function Variable:__call(transform) - if transform == nil then - transform = function(v) - return v - end - return Binding.new(self) - end - return Binding.new(self):as(transform) -end - -function Variable:__tostring() - return "Variable<" .. tostring(self:get()) .. ">" -end - -function Variable:get() - return self._value or nil -end - -function Variable:set(value) - if value ~= self:get() then - self._value = value - self.variable:emit_changed() - end -end - -function Variable:start_poll() - if self._poll ~= nil then - return - end - - if self.poll_fn then - self._poll = Time.interval(self.poll_interval, function() - self:set(self.poll_fn(self:get())) - end) - elseif self.poll_exec then - self._poll = Time.interval(self.poll_interval, function() - Process.exec_async(self.poll_exec, function(out, err) - if err ~= nil then - return self.variable.emit_error(err) - end - self:set(self.poll_transform(out, self:get())) - end) - end) - end -end - -function Variable:start_watch() - if self._watch then - return - end - - self._watch = Process.subprocess(self.watch_exec, function(out) - self:set(self.watch_transform(out, self:get())) - end, function(err) - self.variable.emit_error(err) - end) -end - -function Variable:stop_poll() - if self._poll then - self._poll.cancel() - end - self._poll = nil -end - -function Variable:stop_watch() - if self._watch then - self._watch.kill() - end - self._watch = nil -end - -function Variable:is_polling() - return self._poll ~= nil -end - -function Variable:is_watching() - return self._watch ~= nil -end - -function Variable:drop() - self.variable.emit_dropped() -end - ----@param callback function ----@return Variable -function Variable:on_dropped(callback) - self.variable.on_dropped = callback - return self -end - ----@param callback function ----@return Variable -function Variable:on_error(callback) - self.err_handler = nil - self.variable.on_eror = function(_, err) - callback(err) - end - return self -end - ----@param callback fun(value: any) ----@return function -function Variable:subscribe(callback) - local id = self.variable.on_changed:connect(function() - callback(self:get()) - end) - return function() - GObject.signal_handler_disconnect(self.variable, id) - end -end - ----@param interval number ----@param exec string | string[] | function ----@param transform? fun(next: any, prev: any): any -function Variable:poll(interval, exec, transform) - if transform == nil then - transform = function(next) - return next - end - end - self:stop_poll() - self.poll_interval = interval - self.poll_transform = transform - - if type(exec) == "function" then - self.poll_fn = exec - self.poll_exec = nil - else - self.poll_exec = exec - self.poll_fn = nil - end - self:start_poll() - return self -end - ----@param exec string | string[] ----@param transform? fun(next: any, prev: any): any -function Variable:watch(exec, transform) - if transform == nil then - transform = function(next) - return next - end - end - self:stop_poll() - self.watch_exec = exec - self.watch_transform = transform - self:start_watch() - return self -end - ----@param object table | table[] ----@param sigOrFn string | fun(...): any ----@param callback fun(...): any ----@return Variable -function Variable:observe(object, sigOrFn, callback) - local f - if type(sigOrFn) == "function" then - f = sigOrFn - elseif type(callback) == "function" then - f = callback - else - f = function() - return self:get() - end - end - local set = function(...) - self:set(f(...)) - end - - if type(sigOrFn) == "string" then - object["on_" .. sigOrFn]:connect(set) - else - for _, obj in ipairs(object) do - obj[1]["on_" .. obj[2]]:connect(set) - end - end - return self -end - ----@param deps Variable | (Binding | Variable)[] ----@param transform? fun(...): any ----@return Variable -function Variable.derive(deps, transform) - if type(transform) == "nil" then - transform = function(...) - return { ... } - end - end - - if getmetatable(deps) == Variable then - local var = Variable.new(transform(deps:get())) - deps:subscribe(function(v) - var:set(transform(v)) - end) - return var - end - - for i, var in ipairs(deps) do - if getmetatable(var) == Variable then - deps[i] = Binding.new(var) - end - end - - local update = function() - local params = {} - for i, binding in ipairs(deps) do - params[i] = binding:get() - end - return transform(table.unpack(params), 1, #deps) - end - - local var = Variable.new(update()) - - local unsubs = {} - for i, b in ipairs(deps) do - unsubs[i] = b:subscribe(update) - end - - var.variable.on_dropped = function() - for _, unsub in ipairs(unsubs) do - unsub() - end - end - return var -end - -return setmetatable(Variable, { - __call = function(_, v) - return Variable.new(v) - end, -}) diff --git a/core/lua/astal/widget.lua b/core/lua/astal/widget.lua deleted file mode 100644 index 90831bc..0000000 --- a/core/lua/astal/widget.lua +++ /dev/null @@ -1,322 +0,0 @@ -local lgi = require("lgi") -local Astal = lgi.require("Astal", "0.1") -local Gtk = lgi.require("Gtk", "3.0") -local GObject = lgi.require("GObject", "2.0") -local Binding = require("astal.binding") -local Variable = require("astal.variable") -local exec_async = require("astal.process").exec_async - -local function filter(tbl, fn) - local copy = {} - for key, value in pairs(tbl) do - if fn(value, key) then - if type(key) == "number" then - table.insert(copy, value) - else - copy[key] = value - end - end - end - return copy -end - -local function map(tbl, fn) - local copy = {} - for key, value in pairs(tbl) do - copy[key] = fn(value) - end - return copy -end - -local flatten -flatten = function(tbl) - local copy = {} - for _, value in pairs(tbl) do - if type(value) == "table" and getmetatable(value) == nil then - for _, inner in pairs(flatten(value)) do - table.insert(copy, inner) - end - else - table.insert(copy, value) - end - end - return copy -end - -local function includes(tbl, elem) - for _, value in pairs(tbl) do - if value == elem then - return true - end - end - return false -end - -local function set_children(parent, children) - children = map(flatten(children), function(item) - if Gtk.Widget:is_type_of(item) then - return item - end - return Gtk.Label({ - visible = true, - label = tostring(item), - }) - end) - - -- remove - if Gtk.Bin:is_type_of(parent) then - local ch = parent:get_child() - if ch ~= nil then - parent:remove(ch) - end - if ch ~= nil and not includes(children, ch) and not parent.no_implicit_destroy then - ch:destroy() - end - elseif Gtk.Container:is_type_of(parent) then - for _, ch in ipairs(parent:get_children()) do - parent:remove(ch) - if ch ~= nil and not includes(children, ch) and not parent.no_implicit_destroy then - ch:destroy() - end - end - end - - -- TODO: add more container types - if Astal.Box:is_type_of(parent) then - parent:set_children(children) - elseif Astal.Stack:is_type_of(parent) then - parent:set_children(children) - elseif Astal.CenterBox:is_type_of(parent) then - parent.start_widget = children[1] - parent.center_widget = children[2] - parent.end_widget = children[3] - elseif Astal.Overlay:is_type_of(parent) then - parent:set_child(children[1]) - children[1] = nil - parent:set_overlays(children) - elseif Gtk.Container:is_type_of(parent) then - for _, child in pairs(children) do - if Gtk.Widget:is_type_of(child) then - parent:add(child) - end - end - end -end - -local function merge_bindings(array) - local function get_values(...) - local args = { ... } - local i = 0 - return map(array, function(value) - if getmetatable(value) == Binding then - i = i + 1 - return args[i] - else - return value - end - end) - end - - local bindings = filter(array, function(v) - return getmetatable(v) == Binding - end) - - if #bindings == 0 then - return array - end - - if #bindings == 1 then - return bindings[1]:as(get_values) - end - - return Variable.derive(bindings, get_values)() -end - -local function astalify(ctor) - function ctor:hook(object, signalOrCallback, callback) - if GObject.Object:is_type_of(object) and type(signalOrCallback) == "string" then - local id - if string.sub(signalOrCallback, 1, 8) == "notify::" then - local prop = string.gsub(signalOrCallback, "notify::", "") - id = object.on_notify:connect(function() - callback(self, object[prop]) - end, prop, false) - else - id = object["on_" .. signalOrCallback]:connect(function(_, ...) - callback(self, ...) - end) - end - self.on_destroy = function() - GObject.signal_handler_disconnect(object, id) - end - elseif type(object.subscribe) == "function" then - local unsub = object.subscribe(function(...) - signalOrCallback(self, ...) - end) - self.on_destroy = unsub - else - error("can not hook: not gobject+signal or subscribable") - end - end - - function ctor:toggle_class_name(name, on) - Astal.widget_toggle_class_name(self, name, on) - end - - return function(tbl) - if tbl == nil then - tbl = {} - end - - local bindings = {} - local setup = tbl.setup - - -- collect children - local children = merge_bindings(flatten(filter(tbl, function(_, key) - return type(key) == "number" - end))) - - -- default visible to true - if type(tbl.visible) ~= "boolean" then - tbl.visible = true - end - - -- collect props - local props = filter(tbl, function(_, key) - return type(key) == "string" and key ~= "setup" - end) - - -- collect signal handlers - for prop, value in pairs(props) do - if string.sub(prop, 0, 2) == "on" and type(value) ~= "function" then - props[prop] = function() - exec_async(value, print) - end - end - end - - -- collect bindings - for prop, value in pairs(props) do - if getmetatable(value) == Binding then - bindings[prop] = value - props[prop] = value:get() - end - end - - -- construct, attach bindings, add children - local widget = ctor() - - if getmetatable(children) == Binding then - set_children(widget, children:get()) - widget.on_destroy = children:subscribe(function(v) - set_children(widget, v) - end) - else - if #children > 0 then - set_children(widget, children) - end - end - - for prop, binding in pairs(bindings) do - widget.on_destroy = binding:subscribe(function(v) - widget[prop] = v - end) - end - - for prop, value in pairs(props) do - widget[prop] = value - end - - if type(setup) == "function" then - setup(widget) - end - - return widget - end -end - -local Widget = { - astalify = astalify, - Box = astalify(Astal.Box), - Button = astalify(Astal.Button), - CenterBox = astalify(Astal.CenterBox), - CircularProgress = astalify(Astal.CircularProgress), - DrawingArea = astalify(Gtk.DrawingArea), - Entry = astalify(Gtk.Entry), - EventBox = astalify(Astal.EventBox), - -- TODO: Fixed - -- TODO: FlowBox - Icon = astalify(Astal.Icon), - Label = astalify(Gtk.Label), - LevelBar = astalify(Astal.LevelBar), - -- TODO: ListBox - Overlay = astalify(Astal.Overlay), - Revealer = astalify(Gtk.Revealer), - Scrollable = astalify(Astal.Scrollable), - Slider = astalify(Astal.Slider), - Stack = astalify(Astal.Stack), - Switch = astalify(Gtk.Switch), - Window = astalify(Astal.Window), -} - -Gtk.Widget._attribute.css = { - get = Astal.widget_get_css, - set = Astal.widget_set_css, -} - -Gtk.Widget._attribute.class_name = { - get = function(self) - local result = "" - local strings = Astal.widget_get_class_names(self) - for i, str in ipairs(strings) do - result = result .. str - if i < #strings then - result = result .. " " - end - end - return result - end, - set = function(self, class_name) - local names = {} - for word in class_name:gmatch("%S+") do - table.insert(names, word) - end - Astal.widget_set_class_names(self, names) - end, -} - -Gtk.Widget._attribute.cursor = { - get = Astal.widget_get_cursor, - set = Astal.widget_set_cursor, -} - -Gtk.Widget._attribute.click_through = { - get = Astal.widget_get_click_through, - set = Astal.widget_set_click_through, -} - -local no_implicit_destroy = {} -Gtk.Widget._attribute.no_implicit_destroy = { - get = function(self) - return no_implicit_destroy[self] or false - end, - set = function(self, v) - if no_implicit_destroy[self] == nil then - self.on_destroy = function() - no_implicit_destroy[self] = nil - end - end - no_implicit_destroy[self] = v - end, -} - -Astal.Box._attribute.children = { - get = Astal.Box.get_children, - set = Astal.Box.set_children, -} - -return setmetatable(Widget, { - __call = function(_, ctor) - return astalify(ctor) - end, -}) diff --git a/core/lua/stylua.toml b/core/lua/stylua.toml deleted file mode 100644 index d4a4951..0000000 --- a/core/lua/stylua.toml +++ /dev/null @@ -1,3 +0,0 @@ -indent_type = "Spaces" -indent_width = 4 -column_width = 100 |