Edje Lua scripting

Introduction

Lua is intended for script-only objects at this point (with embryo left for augmenting standard programs). Since script-only objects effectively define objects entirely via Lua script (resize handling, event handling etc. etc.) this places many more demands on them, and thus a more powerful language is in order. Lua is that language.

To get you started, here's an example that uses most of this lua API: lua_script.edc

Most of these lua functions are wrappers around various evas, ecore, and edje C functions. Refer to their documentation for more in depth details and up to date documentation. A lot of this documentation is simple copied from the C functions it wraps.

Lua function argument and return syntax

Some of the lua functions can accept a table as well as separate arguments. Some of them return tables.

Lua classes

Edje class.

The lua edje class includes functions for dealing with the lua script only group as an edje object, basic functions, and functions to create other objects.

In the following, "edje" is the actual global table used to access these edje functions.

edje.echo(text)

Make lua a bit shelly. Prints a string to the console

Parameters
textThe string to print.

edje.date()

Retrieves the current time and date.

Wraps gettimeofday(), as passed through localtime().

Returns
A table with these fields:
  • integer year: Year.
  • integer month: Month of the year.
  • integer day: Day of the month.
  • integer yearday: Day of the year.
  • integer weekday: Day of the week.
  • integer hour: Hour of the day (24 hour format).
  • integer min: Minute of the hour.
  • number sec: Seconds as a number.

edje.looptime()

Retrieves the time at which the last loop stopped waiting for timeouts or events.

This gets the time that the main loop ceased waiting for timouts and/or events to come in or for signals or any other interrupt source. This should be considered a reference point for all time based activity that should calculate its timepoint from the return of edje.looptime(). Use this UNLESS you absolutely must get the current actual timepoint - then use edje.seconds(). Note that this time is meant to be used as relative to other times obtained on this run.

Wraps ecore_loop_time_get().

Returns
A number of seconds.

edje.seconds()

Retrieves the current system time as a floating point value in seconds.

This uses a monotonic clock and thus never goes back in time while machine is live (even if user changes time or timezone changes, however it may be reset whenever the machine is restarted).

Wraps ecore_time_get().

Returns
A number of seconds.

edje.version()

Retrieves the current edje version number.

Returns
A table with these fields:
  • integer major: The edje version major number.
  • integer minor: The edje version minor number.
Since
1.2.0

edje.geom()

Retrieves the position and size of the edje object that this lua group is in.

Returns
A table with these fields:
  • integer x: The edjes X position.
  • integer y: The edjes Y position.
  • integer w: The edjes width.
  • integer h: The edjes height.

edje.pos()

Retrieves the position of the edje object that this lua group is in.

Returns
A table with these fields:
  • integer x: The edjes X position.
  • integer y: The edjes Y position.

edje.size()

Retrieves the size of the edje object that this lua group is in.

Returns
A table with these fields:
  • integer w: The edjes width.
  • integer h: The edjes height.

edje.emit(signal, source)

Emit a signal.

Wraps edje_object_signal_emit().

Parameters
signalThe signal string to send.
sourceThe source string of the signal.

NOTE: The source string will have a name and a colon prepended to in when it is delivered to things that are not this edje, like C and other edje groups. If this edje is a top level edje, then it will be the name of the group (I think). If this edje is swallowed into some other part, then it will be the name of the part:

group_name:source

FIXME: I actually have no idea what happens if it's swallowed into another lua edje group.

edje.messagesend(id, type, ...)

Send a message to this edje, and all it's child objects.

Wraps edje_object_message_send().

Parameters
idAn identification integer for the message.
typeThe type of message to send.
...Zero or more things to send as part of the message, depending on the type.

The type can be one of:

  • none: No msg.
  • sig: The msg is two strings (signal, source), sent as a signal.
  • str: The msg is a C string.
  • int: The message is a C integer.
  • float: The message is a C float.
  • strset: The message is an array of C strings.
  • intset: The message is an array of C integers.
  • floatset: The message is an array of C floats.
  • strint: The message is a C stnring and a C integer.
  • strfloat: The message is a C string and a C float.
  • strintset: The message is a C string and an array of C integers.
  • strfloatset: The message is a G string and an array of C floats.

For the array types, the lua caller passes a table.

edje.animator(func)

This function adds an animator and returns its handle on success and NULL on failure. The function func will be called every frame tick. Note that setting the frame tick is not available as a lua function, so has to be done from C. The default tick is 1/30 second.

When the animator func is called, it must return a value of either true or false. If it returns true it will be called again at the next tick, or if it returns false it will be deleted automatically making any references/handles for it invalid.

Wraps ecore_animator_add().

Parameters
funcThe function to call when the animator triggers.
Returns
A userdata that is an ecore animator.

edje.timer(tick, func)

This function adds a timer and returns its handle on success and NULL on failure. The function func will be called every tick seconds.

When the timer func is called, it must return a value of either true or false. If it returns true, it will be called again at the next tick, or if it returns false it will be deleted automatically making any references/handles for it invalid.

Wraps ecore_timer_add().

Parameters
tickHow often, in seconds, to call the function.
funcThe function to call when the timer triggers.
Returns
A userdata that is an ecore timer.

edje.transition(div, func)

Just like edje.animator(), except that the callback function gets called with an argument. The argument is the amount of time since the transition was created, divided by the div parameter.

Parameters
divA number to divide the time since creation by.
funcThe function to call when the transition triggers.
Returns
A userdata that is a transition (ecore animator, plus other info).

edje.color_class(class, r, g, b, a)

Gets, (and optionally sets) the colours for a color class.

Wraps edje_object_color_class_set().

Parameters
classA color class name.
rThe new red value.
gThe new green value.
bThe new blue value.
aThe new alpha value.

Note that the r, g, b, and a arguments are optional, without them this function just queries the current values. The r, g, b, and a arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer r: The red value.
  • integer g: The green value.
  • integer b: The blue value.
  • integer a: The alpha value.
Since
1.1.0

edje.text_class(class, font, size)

Gets, (and optionally sets) the details for a text class.

Wraps edje_object_text_class_set().

Parameters
classA text class name.
fontThe new font name.
sizeThe new font size.

Note that the font and size arguments are optional, without them this function just queries the current values. The font and size arguments can be separate values, or named fields in a table. The font name can refer to a font in the edje file, or an external font.

Returns
A table with these fields:
  • string font: The font name.
  • integer size: The font size.
Since
1.1.0

edje.edje()

Create an edje object, and add it to the edje.

Wraps edje_object_add().

Returns
A userdata that is an edje object.
Since
1.1.0

edje.image()

Create an evas image, and add it to the edje.

Wraps evas_object_image_add().

Returns
A userdata that is an evas image.
Since
1.1.0

edje.line()

Create an evas line, and add it to the edje.

Wraps evas_object_line_add().

Returns
A userdata that is an evas line.
Since
1.1.0

edje.map()

Create an evas map.

Wraps evas_map_new().

Returns
A userdata that is an evas map.
Since
1.1.0

edje.polygon()

Create an evas polygon, and add it to the edje.

Wraps evas_object_polygon_add().

Returns
A userdata that is an evas polygon.
Since
1.1.0

edje.rect()

Create an evas rectangle, and add it to the edje.

Wraps evas_object_rectangle_add().

Returns
A userdata that is an evas rectangle.

edje.text()

Create an evas text object, and add it to the edje.

Wraps evas_object_text_add().

Returns
A userdata that is an evas text object.
Since
1.1.0

Evas class.

The lua evas class includes functions for dealing with evas objects. The evas objects must have been previously created by lua using one of the lua evas object creation functions from the lua edje class.

In the following, "evas_object" is a place holder for any lua variable that holds a reference to an evas object.

evas_object:hide()

Hides the object.

Wraps evas_object_hide().

Returns
A boolean representing the current visibility.

evas_object:show()

Shows the object.

Wraps evas_object_show().

Returns
A boolean representing the current visibility.

evas_object:visible(visibility)

Gets (and optionally sets) this objects visibility.

Wraps evas_object_hide() or evas_object_show().

Parameters
visibilityThe new visibility you want to change it to.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean representing the current visibility.

evas_object:above()

Figure out what, if anything, is above us.

Wraps evas_object_above_get().

Note that it may not return any value.

Returns
A reference to the object above this one.

evas_object:below()

Figure out what, if anything, is below us.

Wraps evas_object_below_get().

Note that it may not return any value.

Returns
A reference to the object below this one.

evas_object:bottom()

Figure out what, if anything, is waaaay below us.

Note that it may not return any value.

Returns
A reference to the object at the bottom.

evas_object:lower()

Lower this object to the bottom.

Wraps evas_object_lower().

evas_object:raise()

Raise this object to the top.

Wraps evas_object_raise().

evas_object:top()

Figure out what, if anything, is waaaay above us.

Note that it may not return any value.

Returns
A reference to the object at the top.

evas_object:geom(x, y, w, h)

Gets (and optionally sets) this objects geometry.

Wraps evas_object_move() and evas_object_resize.

Parameters
xThe new X coordinate.
yThe new Y coordinate.
wThe new width.
hThe new height.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer x: X coordinate.
  • integer x: Y coordinate.
  • integer w: Width.
  • integer w: Height.

evas_object:move(x, y)

Gets (and optionally sets) this objects position.

Wraps evas_object_move().

Parameters
xThe new X coordinate.
yThe new Y coordinate.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer x: X coordinate.
  • integer x: Y coordinate.

evas_object:pos(x, y)

An alias for evas_object:move().

evas_object:resize(w, h)

Gets (and optionally sets) this objects size.

Wraps evas_object_resize().

Parameters
wThe new width.
hThe new height.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer w: Width.
  • integer w: Height.

evas_object:size()

An alias for evas_object:resize().

evas_object:clip(evas_object2)

Get (and optionally set) the object that clips this object.

Note that the argument is optional, without it this function just queries the current value.

Wraps evas_object_clip_set().

Parameters
evas_object2A reference to the object to clip this object with.
Returns
A reference to the object clipping this object, if any.

evas_object:clipees()

Gets the list of objects this objects clips.

Wraps evas_object_clipees_get().

Returns
A table, that holds all the objects this clips, if any, otherwise an empty table.

evas_object:unclip()

Remove any clipping on this object.

Wraps evas_object_clip_unset().

evas_object:type()

Get the type of this object. See the documentation of the evas_object_type_get() C function for details.

Wraps evas_object_type_get().

Returns
A string with this objects type in it.

evas_object:pass(pass)

Get (and optionally set) whether this object ignores events, passing them to the next object underneath it.

Wraps evas_object_pass_events_set().

Parameters
passA boolean saying if this object passes events.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean saying if this object passes events.

evas_object:precise(precise)

Get (and optionally set) whether to use precise (usually expensive) point collision detection for this object.

Wraps evas_object_precise_is_inside_set().

Parameters
preciseA boolean saying if this object is precisely detected.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean saying if this object is precisely detected.

evas_object:repeat(repeat)

Get (and optionally set) whether this object repeats events.

Wraps evas_object_repeat_events_set().

Parameters
repeatA boolean saying if this object repeats events to lower objects.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean saying if this object repeats events.

evas_object:color(r, g, b, a)

Gets (and optionally sets) this objects colour.

Wraps evas_object_color_set().

Parameters
rThe new red value.
gThe new green value.
bThe new blue value.
aThe new alpha value.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer r: The red value.
  • integer g: The green value.
  • integer b: The blue value.
  • integer a: The alpha value.

evas_object:map(map)

Attach a map to this object.

Wraps evas_object_map_set().

Parameters
mapThe map to attach.
Since
1.1.0

evas_object:map_enable(enable)

Enable or disable the map attached to this object.

Wraps evas_object_map_enable_set().

Parameters
enableA booleon that controls if the attached map is enabled or not.
Returns
A boolean reflecting the map enabled status of this object.
Since
1.1.0

Ecore animator class.

The lua ecore animator class includes functions for dealing with ecore animator objects. The ecore animator objects must have been previously created by lua using the lua edje object creation function edje.animator() or edje.transition().

In the following, "animator_object" is a place holder for any lua variable that holds a reference to an ecore animator object.

Ecore timer class.

The lua ecore timer class includes functions for dealing with ecore timer objects. The ecore timer objects must have been previously created by lua using the lua edje object creation function edje.timer().

In the following, "timer_object" is a place holder for any lua variable that holds a reference to an ecore timer object.

Evas edje class.

The lua evas edje class includes functions for dealing with evas edje objects. The evas edje objects must have been previously created by lua using the lua edje object creation function edje.edje().

In the following, "edje_object" is a place holder for any lua variable that holds a reference to an evas edje object. NOT the edje class specified earlier though.

Since
1.1.0

edje_object:file(file, group)

Load an edje group into this edje object.

Wraps edje_object_file_set().

Parameters
fileAn edje file name (ignored, sandboxed to the file this lua script is in).
groupThe group within the edje file to be loaded.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table. The file argument is optional, and ignored anyway.

Returns
A table with these fields:
  • string file: The name of the edje file this edje's group is loaded from.
  • string group: The name of the group this edje is loaded from.
Since
1.1.0

Evas image class.

The lua evas image class includes functions for dealing with evas image objects. The evas image objects must have been previously created by lua using the lua image object creation function edje.image().

In the following, "image_object" is a place holder for any lua variable that holds a reference to an evas image object.

Since
1.1.0

image_object:fill(x, y, w, h)

Gets (and optionally sets) how to fill this image's drawing rectangle given the (real) image bound to it.

Wraps evas_object_image_fill_set().

Parameters
xThe x coordinate (from the top left corner of the bound image) to start drawing from.
yThe y coordinate (from the top left corner of the bound image) to start drawing from.
wThe width the bound image will be displayed at.
hThe height the bound image will be displayed at.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer x: The x coordinate (from the top left corner of the bound image) to start drawing from.
  • integer y: The y coordinate (from the top left corner of the bound image) to start drawing from.
  • integer w: The width the bound image will be displayed at.
  • integer h: The height the bound image will be displayed at.
Since
1.1.0

image_object:filled(filled)

Get (and optionally set) whether this image fills the object.

Wraps evas_object_image_filled_set().

Parameters
filledA boolean saying if this image fills the object.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean saying if this image fills the object.
Since
1.1.0

image_object:image(file, key)

Load an image into this edje object.

Wraps evas_object_image_file_set().

Parameters
fileAn edje file name (ignored, sandboxed to the file this lua script is in).
groupThe name of an image.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table. The file argument is optional, and ignored anyway.

Returns
A table with these fields:
  • string file: The name of the edje file the image is loaded from.
  • string key: The name of the image within the edje file.
Since
1.1.0

Evas line class.

The lua evas line class includes functions for dealing with evas line objects. The evas line objects must have been previously created by lua using the lua line object creation function edje.line().

In the following, "line_object" is a place holder for any lua variable that holds a reference to an evas line object.

Since
1.1.0

line_object:xy(x1, y1, x2, y2)

Sets the end points of this line.

Wraps evas_object_line_xy_set().

Parameters
x1The X coordinate of the first line end.
y1The Y coordinate of the first line end.
x2The X coordinate of the other line end.
y2The Y coordinate of the other line end.

Note that the arguments are optional, without them this function just queries the current values. The arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer x1: The X coordinate of the first line end.
  • integer y1: The Y coordinate of the first line end.
  • integer x2: The X coordinate of the other line end.
  • integer y2: The Y coordinate of the other line end.
Since
1.1.0

Evas map class.

The lua evas map class includes functions for dealing with evas map objects. The evas map objects must have been previously created by lua using the lua map object creation function edje.map(). The evas map system is complex, rather than repeat the copious documentation here, please refer to the evas map documentation. It has pictures and everything. B-)

In the following, "map_object" is a place holder for any lua variable that holds a reference to an evas map object.

Since
1.1.0

map_object:alpha(alpha)

Get (and optionally set) the maps alpha mode.

Wraps evas_map_alpha_set().

Parameters
alphaThe alpha mode.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean reflecting the alpha mode.
Since
1.1.0

map_object:clockwise()

Get the maps clockwise state.

Wraps evas_map_util_clockwise_get().

Returns
A boolean reflecting if the map is clockwise or not.
Since
1.1.0

map_object:colour(index, r, g, b, a)

Gets or sets colour information for the map. There are two variations, with or without the index. With the index parameter it gets (and optionally sets) the colour of the point the index refers to, without it sets the colour for the entire map.

Wraps evas_map_point_color_set() or evas_map_util_points_color_set()

Parameters
indexWhich point to change the colour of.
rThe new red value.
gThe new green value.
bThe new blue value.
aThe new alpha value.

Note that the arguments are optional, without them this function just queries the current values. The colour arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer r: The red value.
  • integer g: The green value.
  • integer b: The blue value.
  • integer a: The alpha value.
Since
1.1.0

map_object:coord(index, x, y, z)

Gets (and optionally sets) the 3D coordinates of a point on the map.

Wraps evas_map_point_coord_set().

Parameters
xThe x coordinate of the point.
yThe y coordinate of the point.
zThe z coordinate of the point.

Note that the arguments are optional, without them this function just queries the current values. The coordinate arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • integer x: The x coordinate of the point.
  • integer y: The y coordinate of the point.
  • integer z: The z coordinate of the point.
Since
1.1.0

map_object:lighting(x, y, z, r, g, b, ar, ag, ab)

Set the 3D lights for the map. The three triplets can be tables.

Wraps evas_map_util_3d_lighting().

Parameters
xThe x coordinate of the light point.
yThe y coordinate of the light point.
zThe z coordinate of the light point.
rThe new red value of the light point.
gThe new green value of the light point.
bThe new blue value of the light point.
arThe new red value of the ambient light.
agThe new green value of the ambient light.
abThe new blue value of the ambient light.
Since
1.1.0

map_object:perspective(x, y, z, f)

Apply a perspective transform to the map.

Wraps evas_map_util_3d_perspective().

The arguments can be separate values, or named fields in a table.

Parameters
xThe perspective distance X coordinate
yThe perspective distance Y coordinate
zThe "0" z plane value
fThe focal distance
Since
1.1.0

map_object:populate(...)

Populate the points in a map, in one of three different methods.

1) Wraps evas_map_util_points_populate_from_object().

Parameters
sourceAn evas object to copy points from.

2) Wraps evas_map_util_paints_populate_from_object_full().

Parameters
sourceAn evas object to copy points from.
zCommon Z coordinate hint for all four points.

3) Wraps evas_map_util_points_populate_from_geometry().

The first four arguments can be separate values, or named fields in a table.

Parameters
xPoint X coordinate
yPoint Y coordinate
wWidth to use to calculate second and third points.
hHeight to use to calculate third and fourth points.
zCommon Z coordinate hint for all four points.
Since
1.1.0

map_object:rotate(degrees, x, y)

Rotate the maps coordinates in 2D.

Wraps evas_map_util_rotate().

The coordinates can be separate values, or named fields in a table.

Parameters
degreesAmount of degrees from 0.0 to 360.0 to rotate.
xRotation's centre horizontal position.
yRotation's centre vertical position.
Since
1.1.0

map_object:rotate3d(dx, dy, dz, x, y, z)

Rotate the maps coordinates in 3D.

Wraps evas_map_util_3d_rotate().

The coordinates can be separate values, or named fields in a table. The same with the rotation.

Parameters
dxAmount of degrees from 0.0 to 360.0 to rotate around X axis.
dyAmount of degrees from 0.0 to 360.0 to rotate around Y axis.
dzAmount of degrees from 0.0 to 360.0 to rotate around Z axis.
xRotation's centre horizontal position.
yRotation's centre vertical position.
zRotation's centre vertical position.
Since
1.1.0

map_object:smooth(smooth)

Get (and optionally set) the maps smooth mode.

Wraps evas_map_smooth_set().

Parameters
smoothThe smooth mode.

Note that the argument is optional, without it this function just queries the current value.

Returns
A boolean reflecting the smooth mode.
Since
1.1.0

map_object:uv(index, u, v)

Gets (and optionally sets) the texture U and V texture coordinates for this map.

Wraps evas_map_point_image_uv_set().

Parameters
indexIndex of the point to change. Must be smaller than map size.
uThe X coordinate within the image/texture source.
vThe Y coordinate within the image/texture source.

Note that the U,V arguments are optional, without them this function just queries the current values. The coordinate arguments can be separate values, or named fields in a table.

Returns
A table with these fields:
  • number u: The X coordinate within the image/texture source.
  • number v: The Y coordinate within the image/texture source.
Since
1.1.0

map_object:zoom(x, y, x, y)

Apply a zoom to the map.

Wraps evas_map_util_zoom().

The arguments can be two separate values, or named fields in a table.

Parameters
xThe horizontal zoom amount.
yThe vertical zoom amount.
xThe X coordinate of the centre of the zoom.
yThe Y coordinate of the centre of the zoom.
Since
1.1.0

Evas polygon class.

The lua evas polygon class includes functions for dealing with evas polygon objects. The evas polygon objects must have been previously created by lua using the lua polygon object creation function edje.polygon().

In the following, "polygon_object" is a place holder for any lua variable that holds a reference to an evas polygon object.

Since
1.1.0

polygon_object:clear()

Clears all points from the polygon.

Wraps evas_object_polygon_points_clear(),

Since
1.1.0

polygon_object:point(x, y)

Adds a point to this polygon.

Wraps evas_object_polygon_point_add().

Parameters
xThe X coordinate of the point.
yThe Y coordinate of the point.
Since
1.1.0

Evas text class.

The lua evas text class includes functions for dealing with evas text objects. The evas text objects must have been previously created by lua using the lua text object creation function edje.text().

In the following, "text_object" is a place holder for any lua variable that holds a reference to an evas text object.

Since
1.1.0

text_object:font(font, size)

Gets, (and optionally sets) the font for this text object.

Wraps evas_object_text_font_set().

Parameters
fontThe new font name.
sizeThe new font size.

Note that the font and size arguments are optional, without them this function just queries the current values. The font and size arguments can be separate values, or named fields in a table. The font name can refer to a font in the edje file, or an external font.

Returns
A table with these fields:
  • string font: The font name.
  • integer size: The font size.
Since
1.1.0

text_object:text(text)

Get (and optionally set) the actual text for this text object.

Wraps evas_object_text_text_set().

Parameters
textThe text to set for this text object.

Note that the argument is optional, without it this function just queries the current value.

Returns
A string of the text on this text object.
Since
1.1.0

Lua callbacks

These are lua functions that are called by the lua edje system when certain events occur. If the functions don't exist in the lua group, they don't get called.

Edje shutdown() callback.

If a function called "shutdown" exists in a lua edje group, then it is called when that edje gets deleted.

Edje show() callback.

If a function called "show" exists in a lua edje group, then it is called when that edje gets shown.

Edje hide() callback.

If a function called "hide" exists in a lua edje group, then it is called when that edje gets hidden.

Edje move(x, y) callback.

If a function called "move" exists in a lua edje group, then it is called when that edje gets moved, with the new position passed to it.

Edje resize(w, h) callback.

If a function called "resize" exists in a lua edje group, then it is called when that edje gets resized, with the new size passed to it.

Edje message(id, type, ...) callback.

If a function called "message" exists in a lua edje group, then it is called when that edje gets gets a message sent to it, with the message details passed to it. See edje.messagesend() for details of what each type means. The arrays are passed as a table.

Edje signal(signal, source) callback.

If a function called "signal" exists in a lua edje group, then it is called when ever a signal arrives, with the signal details passed to it.