NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

local debug = debug
local coroutine_close = coroutine.close or (function(c) end) -- 5.3 compatibility

-- setup msgpack compat
msgpack.set_string('string_compat')
msgpack.set_integer('unsigned')
msgpack.set_array('without_hole')
msgpack.setoption('empty_table_as_array', true)

-- setup json compat
json.version = json._VERSION -- Version compatibility
json.setoption("empty_table_as_array", true)
json.setoption('with_hole', true)

-- temp
local function FormatStackTrace()
return Citizen.InvokeNative(`FORMAT_STACK_TRACE` & 0xFFFFFFFF, nil, 0, Citizen.ResultAsString())
end

local function ProfilerEnterScope(scopeName)
return Citizen.InvokeNative(`PROFILER_ENTER_SCOPE` & 0xFFFFFFFF, scopeName)
end

local function ProfilerExitScope()
return Citizen.InvokeNative(`PROFILER_EXIT_SCOPE` & 0xFFFFFFFF)
end

local newThreads = {}
local threads = setmetatable({}, {
-- This circumvents undefined behaviour in "next" (and therefore "pairs")
__newindex = newThreads,
-- This is needed for CreateThreadNow to work correctly
__index = newThreads
})

local boundaryIdx = 1
local runningThread

local function dummyUseBoundary(idx)
return nil
end

local function getBoundaryFunc(bfn, bid)
return function(fn, ...)
local boundary = bid or (boundaryIdx + 1)
boundaryIdx = boundaryIdx + 1

bfn(boundary, coroutine.running())

local wrap = function(...)
dummyUseBoundary(boundary)

local v = table.pack(fn(...))
return table.unpack(v)
end

local v = table.pack(wrap(...))

bfn(boundary, nil)

return table.unpack(v)
end
end

local runWithBoundaryStart = getBoundaryFunc(Citizen.SubmitBoundaryStart)
local runWithBoundaryEnd = getBoundaryFunc(Citizen.SubmitBoundaryEnd)

--[[

Thread handling

]]
local function resumeThread(coro) -- Internal utility
if coroutine.status(coro) == "dead" then
threads[coro] = nil
coroutine_close(coro)
return false
end

runningThread = coro

local thread = threads[coro]

if thread then
if thread.name then
ProfilerEnterScope(thread.name)
else
ProfilerEnterScope('thread')
end

Citizen.SubmitBoundaryStart(thread.boundary, coro)
end

local ok, wakeTimeOrErr = coroutine.resume(coro)

if ok then
thread = threads[coro]
if thread then
thread.wakeTime = wakeTimeOrErr or 0
end
else
--Citizen.Trace("Error resuming coroutine: " .. debug.traceback(coro, wakeTimeOrErr) .. "n")
local fst = FormatStackTrace()

if fst then
Citizen.Trace("^1SCRIPT ERROR: " .. wakeTimeOrErr .. "^7n")
Citizen.Trace(fst)
end
end

runningThread = nil

ProfilerExitScope()

-- Return not finished
return coroutine.status(coro) ~= "dead"
end

function Citizen.CreateThread(threadFunction)
local bid = boundaryIdx + 1
boundaryIdx = boundaryIdx + 1

local tfn = function()
return runWithBoundaryStart(threadFunction, bid)
end

local di = debug.getinfo(threadFunction, 'S')

threads[coroutine.create(tfn)] = {
wakeTime = 0,
boundary = bid,
name = ('thread %s[%d..%d]'):format(di.short_src, di.linedefined, di.lastlinedefined)
}
end

function Citizen.Wait(msec)
coroutine.yield(GetGameTimer() + msec)
end

-- legacy alias (and to prevent people from calling the game's function)
Wait = Citizen.Wait
CreateThread = Citizen.CreateThread

function Citizen.CreateThreadNow(threadFunction, name)
local bid = boundaryIdx + 1
boundaryIdx = boundaryIdx + 1

local di = debug.getinfo(threadFunction, 'S')
name = name or ('thread_now %s[%d..%d]'):format(di.short_src, di.linedefined, di.lastlinedefined)

local tfn = function()
return runWithBoundaryStart(threadFunction, bid)
end

local coro = coroutine.create(tfn)
threads[coro] = {
wakeTime = 0,
boundary = bid,
name = name
}
return resumeThread(coro)
end

function Citizen.Await(promise)
local coro = coroutine.running()
if not coro then
error("Current execution context is not in the scheduler, you should use CreateThread / SetTimeout or Event system (AddEventHandler) to be able to Await")
end

-- Indicates if the promise has already been resolved or rejected
-- This is a hack since the API does not expose its state
local isDone = false
local result, err
promise = promise:next(function(...)
isDone = true
result = {...}
end,function(error)
isDone = true
err = error
end)

if not isDone then
local threadData = threads[coro]
threads[coro] = nil

local function reattach()
threads[coro] = threadData
resumeThread(coro)
end

promise:next(reattach, reattach)
Citizen.Wait(0)
end

if err then
error(err)
end

return table.unpack(result)
end

function Citizen.SetTimeout(msec, callback)
local bid = boundaryIdx + 1
boundaryIdx = boundaryIdx + 1

local tfn = function()
return runWithBoundaryStart(callback, bid)
end

local coro = coroutine.create(tfn)
threads[coro] = {
wakeTime = GetGameTimer() + msec,
boundary = bid
}
end

SetTimeout = Citizen.SetTimeout

Citizen.SetTickRoutine(function()
local curTime = GetGameTimer()

for coro, thread in pairs(newThreads) do
rawset(threads, coro, thread)
newThreads[coro] = nil
end

for coro, thread in pairs(threads) do
if curTime >= thread.wakeTime then
resumeThread(coro)
end
end
end)

--[[

Event handling

]]

local alwaysSafeEvents = {
["playerDropped"] = true,
["playerConnecting"] = true
}

local eventHandlers = {}
local deserializingNetEvent = false

Citizen.SetEventRoutine(function(eventName, eventPayload, eventSource)
-- set the event source
local lastSource = _G.source
_G.source = eventSource

-- try finding an event handler for the event
local eventHandlerEntry = eventHandlers[eventName]

-- deserialize the event structure (so that we end up adding references to delete later on)
local data = msgpack.unpack(eventPayload)

if eventHandlerEntry and eventHandlerEntry.handlers then
-- if this is a net event and we don't allow this event to be triggered from the network, return
if eventSource:sub(1, 3) == 'net' then
if not eventHandlerEntry.safeForNet and not alwaysSafeEvents[eventName] then
Citizen.Trace('event ' .. eventName .. " was not safe for netn")

return
end

deserializingNetEvent = { source = eventSource }
_G.source = tonumber(eventSource:sub(5))
end

-- return an empty table if the data is nil
if not data then
data = {}
end

-- reset serialization
deserializingNetEvent = nil

-- if this is a table...
if type(data) == 'table' then
-- loop through all the event handlers
for k, handler in pairs(eventHandlerEntry.handlers) do
local di = debug.getinfo(handler)

Citizen.CreateThreadNow(function()
handler(table.unpack(data))
end, ('event %s [%s[%d..%d]]'):format(eventName, di.short_src, di.linedefined, di.lastlinedefined))
end
end
end

_G.source = lastSource
end)

local stackTraceBoundaryIdx

Citizen.SetStackTraceRoutine(function(bs, ts, be, te)
if not ts then
ts = runningThread
end

local t
local n = 1

local frames = {}
local skip = false

if bs then
skip = true
end

repeat
if ts then
t = debug.getinfo(ts, n, 'nlfS')
else
t = debug.getinfo(n, 'nlfS')
end

if t then
if t.name == 'wrap' and t.source == '@citizen:/scripting/lua/scheduler.lua' then
if not stackTraceBoundaryIdx then
local b, v
local u = 1

repeat
b, v = debug.getupvalue(t.func, u)

if b == 'boundary' then
break
end

u = u + 1
until not b

stackTraceBoundaryIdx = u
end

local _, boundary = debug.getupvalue(t.func, stackTraceBoundaryIdx)

if boundary == bs then
skip = false
end

if boundary == be then
break
end
end

if not skip then
if t.source and t.source:sub(1, 1) ~= '=' and t.source:sub(1, 10) ~= '@citizen:/' then
table.insert(frames, {
file = t.source:sub(2),
line = t.currentline,
name = t.name or '[global chunk]'
})
end
end

n = n + 1
end
until not t

return msgpack.pack(frames)
end)

local eventKey = 10

function AddEventHandler(eventName, eventRoutine)
local tableEntry = eventHandlers[eventName]

if not tableEntry then
tableEntry = { }

eventHandlers[eventName] = tableEntry
end

if not tableEntry.handlers then
tableEntry.handlers = { }
end

eventKey = eventKey + 1
tableEntry.handlers[eventKey] = eventRoutine

RegisterResourceAsEventHandler(eventName)

return {
key = eventKey,
name = eventName
}
end

function RemoveEventHandler(eventData)
if not eventData.key and not eventData.name then
error('Invalid event data passed to RemoveEventHandler()')
end

-- remove the entry
eventHandlers[eventData.name].handlers[eventData.key] = nil
end

function RegisterNetEvent(eventName)
local tableEntry = eventHandlers[eventName]

if not tableEntry then
tableEntry = { }

eventHandlers[eventName] = tableEntry
end

tableEntry.safeForNet = true
end

function TriggerEvent(eventName, ...)
local payload = msgpack.pack({...})

return runWithBoundaryEnd(function()
return TriggerEventInternal(eventName, payload, payload:len())
end)
end

if IsDuplicityVersion() then
function TriggerClientEvent(eventName, playerId, ...)
local payload = msgpack.pack({...})

return TriggerClientEventInternal(eventName, playerId, payload, payload:len())
end

function TriggerLatentClientEvent(eventName, playerId, bps, ...)
local payload = msgpack.pack({...})

return TriggerLatentClientEventInternal(eventName, playerId, payload, payload:len(), tonumber(bps))
end

RegisterServerEvent = RegisterNetEvent
RconPrint = Citizen.Trace
GetPlayerEP = GetPlayerEndpoint
RconLog = function() end

function GetPlayerIdentifiers(player)
local numIds = GetNumPlayerIdentifiers(player)
local t = {}

for i = 0, numIds - 1 do
table.insert(t, GetPlayerIdentifier(player, i))
end

return t
end

function GetPlayers()
local num = GetNumPlayerIndices()
local t = {}

for i = 0, num - 1 do
table.insert(t, GetPlayerFromIndex(i))
end

return t
end

local httpDispatch = {}
AddEventHandler('__cfx_internal:httpResponse', function(token, status, body, headers)
if httpDispatch[token] then
local userCallback = httpDispatch[token]
httpDispatch[token] = nil
userCallback(status, body, headers)
end
end)

function PerformHttpRequest(url, cb, method, data, headers)
local t = {
url = url,
method = method or 'GET',
data = data or '',
headers = headers or {}
}

local d = json.encode(t)
local id = PerformHttpRequestInternal(d, d:len())

httpDispatch[id] = cb
end
else
function TriggerServerEvent(eventName, ...)
local payload = msgpack.pack({...})

return TriggerServerEventInternal(eventName, payload, payload:len())
end

function TriggerLatentServerEvent(eventName, bps, ...)
local payload = msgpack.pack({...})

return TriggerLatentServerEventInternal(eventName, payload, payload:len(), tonumber(bps))
end
end

local funcRefs = {}
local funcRefIdx = 0

local function MakeFunctionReference(func)
local thisIdx = funcRefIdx

funcRefs[thisIdx] = {
func = func,
refs = 0
}

funcRefIdx = funcRefIdx + 1

local refStr = Citizen.CanonicalizeRef(thisIdx)
return refStr
end

function Citizen.GetFunctionReference(func)
if type(func) == 'function' then
return MakeFunctionReference(func)
elseif type(func) == 'table' and rawget(func, '__cfx_functionReference') then
return MakeFunctionReference(function(...)
return func(...)
end)
end

return nil
end

local function doStackFormat(err)
local fst = FormatStackTrace()

-- already recovering from an error
if not fst then
return nil
end

return '^1SCRIPT ERROR: ' .. err .. "^7n" .. fst
end

Citizen.SetCallRefRoutine(function(refId, argsSerialized)
local refPtr = funcRefs[refId]

if not refPtr then
Citizen.Trace('Invalid ref call attempt: ' .. refId .. "n")

return msgpack.pack({})
end

local ref = refPtr.func

local err
local retvals
local cb = {}

local di = debug.getinfo(ref)

local waited = Citizen.CreateThreadNow(function()
local status, result, error = xpcall(function()
retvals = { ref(table.unpack(msgpack.unpack(argsSerialized))) }
end, doStackFormat)

if not status then
err = result or ''
end

if cb.cb then
cb.cb(retvals or false, err)
end
end, ('ref call [%s[%d..%d]]'):format(di.short_src, di.linedefined, di.lastlinedefined))

if not waited then
if err then
--error(err)
if err ~= '' then
Citizen.Trace(err)
end

return msgpack.pack(nil)
end

return msgpack.pack(retvals)
else
return msgpack.pack({{
__cfx_async_retval = function(rvcb)
cb.cb = rvcb
end
}})
end
end)

Citizen.SetDuplicateRefRoutine(function(refId)
local ref = funcRefs[refId]

if ref then
--print(('%s %s ref %d - new refcount %d (from %s)'):format(GetCurrentResourceName(), 'duplicating', refId, ref.refs + 1, GetInvokingResource() or 'nil'))

ref.refs = ref.refs + 1

return refId
end

return -1
end)

Citizen.SetDeleteRefRoutine(function(refId)
local ref = funcRefs[refId]

if ref then
--print(('%s %s ref %d - new refcount %d (from %s)'):format(GetCurrentResourceName(), 'deleting', refId, ref.refs - 1, GetInvokingResource() or 'nil'))

ref.refs = ref.refs - 1

if ref.refs <= 0 then
funcRefs[refId] = nil
end
end
end)

-- RPC REQUEST HANDLER
local InvokeRpcEvent

if GetCurrentResourceName() == 'sessionmanager' then
local rpcEvName = ('__cfx_rpcReq')

RegisterNetEvent(rpcEvName)

AddEventHandler(rpcEvName, function(retEvent, retId, refId, args)
local source = source

local eventTriggerFn = TriggerServerEvent

if IsDuplicityVersion() then
eventTriggerFn = function(name, ...)
TriggerClientEvent(name, source, ...)
end
end

local returnEvent = function(args, err)
eventTriggerFn(retEvent, retId, args, err)
end

local function makeArgRefs(o)
if type(o) == 'table' then
for k, v in pairs(o) do
if type(v) == 'table' and rawget(v, '__cfx_functionReference') then
o[k] = function(...)
return InvokeRpcEvent(source, rawget(v, '__cfx_functionReference'), {...})
end
end

makeArgRefs(v)
end
end
end

makeArgRefs(args)

runWithBoundaryEnd(function()
local payload = Citizen.InvokeFunctionReference(refId, msgpack.pack(args))

if #payload == 0 then
returnEvent(false, 'err')
return
end

local rvs = msgpack.unpack(payload)

if type(rvs[1]) == 'table' and rvs[1].__cfx_async_retval then
rvs[1].__cfx_async_retval(returnEvent)
else
returnEvent(rvs)
end
end)
end)
end

local rpcId = 0
local rpcPromises = {}
local playerPromises = {}

-- RPC REPLY HANDLER
local repName = ('__cfx_rpcRep:%s'):format(GetCurrentResourceName())

RegisterNetEvent(repName)

AddEventHandler(repName, function(retId, args, err)
local promise = rpcPromises[retId]
rpcPromises[retId] = nil

-- remove any player promise for us
for k, v in pairs(playerPromises) do
v[retId] = nil
end

if promise then
if args then
promise:resolve(args[1])
elseif err then
promise:reject(err)
end
end
end)

if IsDuplicityVersion() then
AddEventHandler('playerDropped', function(reason)
local source = source

if playerPromises[source] then
for k, v in pairs(playerPromises[source]) do
local p = rpcPromises[k]

if p then
p:reject('Player dropped: ' .. reason)
end
end
end

playerPromises[source] = nil
end)
end

local EXT_FUNCREF = 10
local EXT_LOCALFUNCREF = 11

msgpack.extend_clear(EXT_FUNCREF, EXT_LOCALFUNCREF)

-- RPC INVOCATION
InvokeRpcEvent = function(source, ref, args)
if not coroutine.running() then
error('RPC delegates can only be invoked from a thread.')
end

local src = source

local eventTriggerFn = TriggerServerEvent

if IsDuplicityVersion() then
eventTriggerFn = function(name, ...)
TriggerClientEvent(name, src, ...)
end
end

local p = promise.new()
local asyncId = rpcId
rpcId = rpcId + 1

local refId = ('%d:%d'):format(GetInstanceId(), asyncId)

eventTriggerFn('__cfx_rpcReq', repName, refId, ref, args)

-- add rpc promise
rpcPromises[refId] = p

-- add a player promise
if not playerPromises[src] then
playerPromises[src] = {}
end

playerPromises[src][refId] = true

return Citizen.Await(p)
end

local funcref_mt = nil

funcref_mt = msgpack.extend({
__gc = function(t)
DeleteFunctionReference(rawget(t, '__cfx_functionReference'))
end,

__index = function(t, k)
error('Cannot index a funcref')
end,

__newindex = function(t, k, v)
error('Cannot set indexes on a funcref')
end,

__call = function(t, ...)
local netSource = rawget(t, '__cfx_functionSource')
local ref = rawget(t, '__cfx_functionReference')

if not netSource then
local args = msgpack.pack({...})

-- as Lua doesn't allow directly getting lengths from a data buffer, and _s will zero-terminate, we have a wrapper in the game itself
local rv = runWithBoundaryEnd(function()
return Citizen.InvokeFunctionReference(ref, args)
end)
local rvs = msgpack.unpack(rv)

-- handle async retvals from refs
if rvs and type(rvs[1]) == 'table' and rawget(rvs[1], '__cfx_async_retval') and coroutine.running() then
local p = promise.new()

rvs[1].__cfx_async_retval(function(r, e)
if r then
p:resolve(r)
elseif e then
p:reject(e)
end
end)

return table.unpack(Citizen.Await(p))
end

return table.unpack(rvs)
else
return InvokeRpcEvent(tonumber(netSource.source:sub(5)), ref, {...})
end
end,

__ext = EXT_FUNCREF,

__pack = function(self, tag)
local refstr = Citizen.GetFunctionReference(self)
if refstr then
return refstr
else
error(("Unknown funcref type: %d %s"):format(tag, type(self)))
end
end,

__unpack = function(data, tag)
local ref = data

-- add a reference
DuplicateFunctionReference(ref)

local tbl = {
__cfx_functionReference = ref,
__cfx_functionSource = deserializingNetEvent
}

if tag == EXT_LOCALFUNCREF then
tbl.__cfx_functionSource = nil
end

tbl = setmetatable(tbl, funcref_mt)

return tbl
end,
})

--[[ Also initialize unpackers for local function references --]]
msgpack.extend({
__ext = EXT_LOCALFUNCREF,
__pack = funcref_mt.__pack,
__unpack = funcref_mt.__unpack,
})

msgpack.settype("function", EXT_FUNCREF)

-- exports compatibility
local function getExportEventName(resource, name)
return string.format('__cfx_export_%s_%s', resource, name)
end

-- callback cache to avoid extra call to serialization / deserialization process at each time getting an export
local exportsCallbackCache = {}

local exportKey = (IsDuplicityVersion() and 'server_export' or 'export')

AddEventHandler(('on%sResourceStart'):format(IsDuplicityVersion() and 'Server' or 'Client'), function(resource)
if resource == GetCurrentResourceName() then
local numMetaData = GetNumResourceMetadata(resource, exportKey) or 0

for i = 0, numMetaData-1 do
local exportName = GetResourceMetadata(resource, exportKey, i)

AddEventHandler(getExportEventName(resource, exportName), function(setCB)
-- get the entry from *our* global table and invoke the set callback
if _G[exportName] then
setCB(_G[exportName])
end
end)
end
end
end)

-- Remove cache when resource stop to avoid calling unexisting exports
AddEventHandler(('on%sResourceStop'):format(IsDuplicityVersion() and 'Server' or 'Client'), function(resource)
exportsCallbackCache[resource] = {}
end)

-- invocation bit
exports = {}

setmetatable(exports, {
__index = function(t, k)
local resource = k

return setmetatable({}, {
__index = function(t, k)
if not exportsCallbackCache[resource] then
exportsCallbackCache[resource] = {}
end

if not exportsCallbackCache[resource][k] then
TriggerEvent(getExportEventName(resource, k), function(exportData)
exportsCallbackCache[resource][k] = exportData
end)

if not exportsCallbackCache[resource][k] then
error('No such export ' .. k .. ' in resource ' .. resource)
end
end

return function(self, ...)
local status, result = pcall(exportsCallbackCache[resource][k], ...)

if not status then
error('An error happened while calling export ' .. k .. ' of resource ' .. resource .. ' (' .. result .. '), see above for details')
end

return result
end
end,

__newindex = function(t, k, v)
error('cannot set values on an export resource')
end
})
end,

__newindex = function(t, k, v)
error('cannot set values on exports')
end,

__call = function(t, exportName, func)
AddEventHandler(getExportEventName(GetCurrentResourceName(), exportName), function(setCB)
setCB(func)
end)
end
})

-- NUI callbacks
if not IsDuplicityVersion() then
function RegisterNUICallback(type, callback)
RegisterNuiCallbackType(type)

AddEventHandler('__cfx_nui:' .. type, function(body, resultCallback)
local status, err = pcall(function()
callback(body, resultCallback)
end)

if err then
Citizen.Trace("error during NUI callback " .. type .. ": " .. err .. "n")
end
end)
end

local _sendNuiMessage = SendNuiMessage

function SendNUIMessage(message)
_sendNuiMessage(json.encode(message))
end
end

-- entity helpers
local EXT_ENTITY = 41
local EXT_PLAYER = 42

msgpack.extend_clear(EXT_ENTITY, EXT_PLAYER)

local function NewStateBag(es)
local sv = IsDuplicityVersion()

return setmetatable({}, {
__index = function(_, s)
if s == 'set' then
return function(_, s, v, r)
local payload = msgpack.pack(v)
SetStateBagValue(es, s, payload, payload:len(), r)
end
end

return GetStateBagValue(es, s)
end,

__newindex = function(_, s, v)
local payload = msgpack.pack(v)
SetStateBagValue(es, s, payload, payload:len(), sv)
end
})
end

GlobalState = NewStateBag('global')

local entityTM = {
__index = function(t, s)
if s == 'state' then
local es = ('entity:%d'):format(NetworkGetNetworkIdFromEntity(t.__data))

if IsDuplicityVersion() then
EnsureEntityStateBag(t.__data)
end

return NewStateBag(es)
end

return nil
end,

__newindex = function()
error('Not allowed at this time.')
end,

__ext = EXT_ENTITY,

__pack = function(self, t)
return tostring(NetworkGetNetworkIdFromEntity(self.__data))
end,

__unpack = function(data, t)
local ref = NetworkGetEntityFromNetworkId(tonumber(data))

return setmetatable({
__data = ref
}, entityTM)
end
}

msgpack.extend(entityTM)

local playerTM = {
__index = function(t, s)
if s == 'state' then
local pid = t.__data

if pid == -1 then
pid = GetPlayerServerId(PlayerId())
end

local es = ('player:%d'):format(pid)

return NewStateBag(es)
end

return nil
end,

__newindex = function()
error('Not allowed at this time.')
end,

__ext = EXT_PLAYER,

__pack = function(self, t)
return tostring(self.__data)
end,

__unpack = function(data, t)
local ref = tonumber(data)

return setmetatable({
__data = ref
}, playerTM)
end
}

msgpack.extend(playerTM)

function Entity(ent)
if type(ent) == 'number' then
return setmetatable({
__data = ent
}, entityTM)
end

return ent
end

function Player(ent)
if type(ent) == 'number' or type(ent) == 'string' then
return setmetatable({
__data = tonumber(ent)
}, playerTM)
end

return ent
end

if not IsDuplicityVersion() then
LocalPlayer = Player(-1)
end
     
 
what is notes.io
 

Notes is a web-based application for online taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000+ notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 14 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.