Update content of files

This commit is contained in:
GitHub Action 2022-01-14 08:27:23 +00:00
parent f36c523a1e
commit a7bcac37a4
8 changed files with 3480 additions and 927 deletions

View file

@ -1,297 +0,0 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Channel statistics</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="Telegram offers detailed channel statistics for channels and supergroups.">
<meta property="og:title" content="Channel statistics">
<meta property="og:image" content="">
<meta property="og:description" content="Telegram offers detailed channel statistics for channels and supergroups.">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class="active"><a href="/api">API</a></li>
<li class=""><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/api" >API</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/api/stats" >Channel statistics</a></li></ul></div>
<h1 id="dev_page_title">Channel statistics</h1>
<div id="dev_page_content"><!-- scroll_nav -->
<p>Telegram offers detailed channel statistics for channels and supergroups. </p>
<h3><a class="anchor" href="#channel-statistics" id="channel-statistics" name="channel-statistics"><i class="anchor-icon"></i></a>Channel statistics</h3>
<p>Schema:</p>
<pre><code><a href='/constructor/statsDateRangeDays'>statsDateRangeDays</a>#b637edaf min_date:<a href='/type/int'>int</a> max_date:<a href='/type/int'>int</a> = <a href='/type/StatsDateRangeDays'>StatsDateRangeDays</a>;
<a href='/constructor/statsAbsValueAndPrev'>statsAbsValueAndPrev</a>#cb43acde current:<a href='/type/double'>double</a> previous:<a href='/type/double'>double</a> = <a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a>;
<a href='/constructor/statsPercentValue'>statsPercentValue</a>#cbce2fe0 part:<a href='/type/double'>double</a> total:<a href='/type/double'>double</a> = <a href='/type/StatsPercentValue'>StatsPercentValue</a>;
<a href='/constructor/statsGraphAsync'>statsGraphAsync</a>#4a27eb2d token:<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/statsGraphError'>statsGraphError</a>#bedc9822 error:<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/statsGraph'>statsGraph</a>#8ea464b6 flags:<a href='/type/%23'>#</a> json:<a href='/type/DataJSON'>DataJSON</a> zoom_token:flags.0?<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/messageInteractionCounters'>messageInteractionCounters</a>#ad4fc9bd msg_id:<a href='/type/int'>int</a> views:<a href='/type/int'>int</a> forwards:<a href='/type/int'>int</a> = <a href='/type/MessageInteractionCounters'>MessageInteractionCounters</a>;
<a href='/constructor/stats.broadcastStats'>stats.broadcastStats</a>#bdf78394 period:<a href='/type/StatsDateRangeDays'>StatsDateRangeDays</a> followers:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> views_per_post:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> shares_per_post:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> enabled_notifications:<a href='/type/StatsPercentValue'>StatsPercentValue</a> growth_graph:<a href='/type/StatsGraph'>StatsGraph</a> followers_graph:<a href='/type/StatsGraph'>StatsGraph</a> mute_graph:<a href='/type/StatsGraph'>StatsGraph</a> top_hours_graph:<a href='/type/StatsGraph'>StatsGraph</a> interactions_graph:<a href='/type/StatsGraph'>StatsGraph</a> iv_interactions_graph:<a href='/type/StatsGraph'>StatsGraph</a> views_by_source_graph:<a href='/type/StatsGraph'>StatsGraph</a> new_followers_by_source_graph:<a href='/type/StatsGraph'>StatsGraph</a> languages_graph:<a href='/type/StatsGraph'>StatsGraph</a> recent_message_interactions:<a href='/type/Vector%20t'>Vector</a>&lt;<a href='/type/MessageInteractionCounters'>MessageInteractionCounters</a>&gt; = <a href='/type/stats.BroadcastStats'>stats.BroadcastStats</a>;
---functions---
<a href='/method/stats.getBroadcastStats'>stats.getBroadcastStats</a>#ab42441a flags:<a href='/type/%23'>#</a> dark:flags.0?<a href='/constructor/true'>true</a> channel:<a href='/type/InputChannel'>InputChannel</a> = <a href='/type/stats.BroadcastStats'>stats.BroadcastStats</a>;
<a href='/method/stats.loadAsyncGraph'>stats.loadAsyncGraph</a>#621d5fa0 flags:<a href='/type/%23'>#</a> token:<a href='/type/string'>string</a> x:flags.0?<a href='/type/long'>long</a> = <a href='/type/StatsGraph'>StatsGraph</a>;</code></pre>
<p>Administrators of <a href="/api/channel">channels</a> of a certain size (the exact limit is a server-side config, returned in the <code>can_view_stats</code> flag of <a href="/constructor/channelFull">channelFull</a>) can call <a href="/method/stats.getBroadcastStats">stats.getBroadcastStats</a> to get detailed channel statistics.<br>
The returned <a href="/constructor/stats.broadcastStats">stats.broadcastStats</a> contains multiple statistics: </p>
<ul>
<li>Period-related statistics: a pair of values, one at the beginning and one at the end of the period in consideration (<code>period</code>). <br> The <code>period</code> typically depends on channel activity.<ul>
<li>Absolute follower count (<code>followers</code>)</li>
<li><code>total_viewcount/postcount</code>, for posts posted during the period in consideration (<code>views_per_post</code>).<br>
Note that in this case, <code>current</code> refers to the <code>period</code> in consideration (<code>min_date</code> till <code>max_date</code>), and <code>prev</code> refers to the previous period (<code>(min_date - (max_date - min_date))</code> till <code>min_date</code>). </li>
<li><code>total_sharecount/postcount</code>, for posts posted during the period in consideration (<code>shares_per_post</code>).<br>
Note that in this case, <code>current</code> refers to the <code>period</code> in consideration (<code>min_date</code> till <code>max_date</code>), and <code>prev</code> refers to the previous period (<code>(min_date - (max_date - min_date))</code> till <code>min_date</code>).</li>
</ul>
</li>
<li>Percentage statistics<ul>
<li>Percentage of subscribers with enabled notifications (<code>enabled_notifications</code>)</li>
</ul>
</li>
<li>Graphs: <a href="#graph-visualization">graphs are described below »</a>. </li>
</ul>
<h3><a class="anchor" href="#supergroup-statistics" id="supergroup-statistics" name="supergroup-statistics"><i class="anchor-icon"></i></a>Supergroup statistics</h3>
<p>Schema:</p>
<pre><code><a href='/constructor/statsGroupTopPoster'>statsGroupTopPoster</a>#9d04af9b user_id:<a href='/type/long'>long</a> messages:<a href='/type/int'>int</a> avg_chars:<a href='/type/int'>int</a> = <a href='/type/StatsGroupTopPoster'>StatsGroupTopPoster</a>;
<a href='/constructor/statsGroupTopInviter'>statsGroupTopInviter</a>#535f779d user_id:<a href='/type/long'>long</a> invitations:<a href='/type/int'>int</a> = <a href='/type/StatsGroupTopInviter'>StatsGroupTopInviter</a>;
<a href='/constructor/statsGroupTopAdmin'>statsGroupTopAdmin</a>#d7584c87 user_id:<a href='/type/long'>long</a> deleted:<a href='/type/int'>int</a> kicked:<a href='/type/int'>int</a> banned:<a href='/type/int'>int</a> = <a href='/type/StatsGroupTopAdmin'>StatsGroupTopAdmin</a>;
<a href='/constructor/stats.megagroupStats'>stats.megagroupStats</a>#ef7ff916 period:<a href='/type/StatsDateRangeDays'>StatsDateRangeDays</a> members:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> messages:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> viewers:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> posters:<a href='/type/StatsAbsValueAndPrev'>StatsAbsValueAndPrev</a> growth_graph:<a href='/type/StatsGraph'>StatsGraph</a> members_graph:<a href='/type/StatsGraph'>StatsGraph</a> new_members_by_source_graph:<a href='/type/StatsGraph'>StatsGraph</a> languages_graph:<a href='/type/StatsGraph'>StatsGraph</a> messages_graph:<a href='/type/StatsGraph'>StatsGraph</a> actions_graph:<a href='/type/StatsGraph'>StatsGraph</a> top_hours_graph:<a href='/type/StatsGraph'>StatsGraph</a> weekdays_graph:<a href='/type/StatsGraph'>StatsGraph</a> top_posters:<a href='/type/Vector%20t'>Vector</a>&lt;<a href='/type/StatsGroupTopPoster'>StatsGroupTopPoster</a>&gt; top_admins:<a href='/type/Vector%20t'>Vector</a>&lt;<a href='/type/StatsGroupTopAdmin'>StatsGroupTopAdmin</a>&gt; top_inviters:<a href='/type/Vector%20t'>Vector</a>&lt;<a href='/type/StatsGroupTopInviter'>StatsGroupTopInviter</a>&gt; users:<a href='/type/Vector%20t'>Vector</a>&lt;<a href='/type/User'>User</a>&gt; = <a href='/type/stats.MegagroupStats'>stats.MegagroupStats</a>;
---functions---
<a href='/method/stats.getMegagroupStats'>stats.getMegagroupStats</a>#dcdf8607 flags:<a href='/type/%23'>#</a> dark:flags.0?<a href='/constructor/true'>true</a> channel:<a href='/type/InputChannel'>InputChannel</a> = <a href='/type/stats.MegagroupStats'>stats.MegagroupStats</a>;</code></pre>
<p>Administrators of <a href="/api/channel">supergroups</a> of a certain size (the exact limit is a server-side config, returned in the <code>can_view_stats</code> flag of <a href="/constructor/channelFull">channelFull</a>) can call <a href="/method/stats.getMegagroupStats">stats.getMegagroupStats</a> to get detailed supergroup statistics.<br>
The returned <a href="/constructor/stats.broadcastStats">stats.broadcastStats</a> contains multiple statistics, see the <a href="/constructor/stats.broadcastStats">constructor page for more info »</a>. </p>
<h3><a class="anchor" href="#message-statistics" id="message-statistics" name="message-statistics"><i class="anchor-icon"></i></a>Message statistics</h3>
<pre><code><a href='/constructor/stats.messageStats'>stats.messageStats</a>#8999f295 views_graph:<a href='/type/StatsGraph'>StatsGraph</a> = <a href='/type/stats.MessageStats'>stats.MessageStats</a>;
---functions---
<a href='/method/stats.getMessageStats'>stats.getMessageStats</a>#b6e0a3f5 flags:<a href='/type/%23'>#</a> dark:flags.0?<a href='/constructor/true'>true</a> channel:<a href='/type/InputChannel'>InputChannel</a> msg_id:<a href='/type/int'>int</a> = <a href='/type/stats.MessageStats'>stats.MessageStats</a>;</code></pre>
<p>Administrators of <a href="/api/channel">channels</a> of a certain size (the exact limit is a server-side config, returned in the <code>can_view_stats</code> flag of <a href="/constructor/channelFull">channelFull</a>) can call <a href="/method/stats.getMessageStats">stats.getMessageStats</a> to get statistics of a specific message.<br>
The returned <a href="/constructor/stats.messageStats">stats.messageStats</a> contains the view graph of the message. </p>
<h2><a class="anchor" href="#graph-visualization" id="graph-visualization" name="graph-visualization"><i class="anchor-icon"></i></a>Graph visualization</h2>
<p>There are four available visualizations for graph types:</p>
<ul>
<li><a href="#line-graph">Line graph</a></li>
<li><a href="#step-graph">Step graph</a></li>
<li><a href="#bar-graph">Bar graph</a></li>
<li><a href="#area-graph">Area graph</a></li>
</ul>
<p>Graph modifiers (see <a href="#graph-examples">various graphs</a> for examples): </p>
<ul>
<li><code>y_scaled</code> - Indicates that each of the two (!) lines in a step graph must be visualized on its own scale, with two different tick axes on the left and right parts of the graph</li>
<li><code>percentage</code> - Indicates whether value percentages should be shown in labels</li>
<li><code>stacked</code> - Depending on the graph type, indicates stacking of multiple columns in the same graph</li>
</ul>
<h3><a class="anchor" href="#graph-syntax" id="graph-syntax" name="graph-syntax"><i class="anchor-icon"></i></a>Graph syntax</h3>
<pre><code><a href='/constructor/statsGraphAsync'>statsGraphAsync</a>#4a27eb2d token:<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/statsGraphError'>statsGraphError</a>#bedc9822 error:<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/statsGraph'>statsGraph</a>#8ea464b6 flags:<a href='/type/%23'>#</a> json:<a href='/type/DataJSON'>DataJSON</a> zoom_token:flags.0?<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/dataJSON'>dataJSON</a>#7d748d04 data:<a href='/type/string'>string</a> = <a href='/type/DataJSON'>DataJSON</a>;
---functions---
<a href='/method/stats.loadAsyncGraph'>stats.loadAsyncGraph</a>#621d5fa0 flags:<a href='/type/%23'>#</a> token:<a href='/type/string'>string</a> x:flags.0?<a href='/type/long'>long</a> = <a href='/type/StatsGraph'>StatsGraph</a>;</code></pre>
<p>Certain graphs are not directly sent in the <a href="/constructor/stats.broadcastStats">stats.broadcastStats</a> constructor to reduce server load: instead, those graphs will be sent as a <a href="/constructor/statsGraphAsync">statsGraphAsync</a> constructor, and should be fetched separately using <a href="/method/stats.loadAsyncGraph">stats.loadAsyncGraph</a>. </p>
<p>After obtaining the full <a href="/constructor/statsGraph">statsGraph</a> constructor, clients should parse the JSON graph object in the <code>json</code> field.</p>
<p>Object structure: </p>
<table class="table">
<thead>
<tr>
<th>Key</th>
<th>Graph title</th>
</tr>
</thead>
<tbody>
<tr>
<td>columns</td>
<td>Array of all data column arrays in the chart. Each column array has its <strong>label</strong> at position 0, followed by values.</td>
</tr>
<tr>
<td>types</td>
<td><a href="#graphs">Graphs types</a> for each of the column arrays (object, <code>"label": "type"</code>): <br>- <code>line</code> - <a href="#line-graph">line graph</a> <br>- <code>area</code> - <a href="#area-graph">area graph</a> <br>- <code>step</code> - <a href="#step-graph">step graph</a> <br>- <code>bar</code> - <a href="#bar-graph">bar graph</a> <br>- <code>x</code> - x axis values for each of the charts at the corresponding positions, UNIX timestamps in milliseconds.</td>
</tr>
<tr>
<td>colors</td>
<td>Color for each type (object, <code>"label": "colorKey#AAAAAA"</code>; see <a href="#chart-colors">chart colors</a>).</td>
</tr>
<tr>
<td>names</td>
<td>Localized name for each variable (object, <code>"label": "Name"</code>)</td>
</tr>
<tr>
<td>subchart</td>
<td>Object indicating the default zoom range for the graph, this is object's structure: <br>- <code>show</code> - Whether to use the specified zoom range (boolean) <br>- <code>defaultZoom</code> - An array with two <code>x</code> values, indicating the two ends of the default zoom range</td>
</tr>
<tr>
<td>y_scaled</td>
<td>Indicates that each of the two (!) lines in a step graph must be visualized on its own scale, with two different tick axes on the left and right parts of the graph (boolean, see <a href="#graph-examples">various graphs</a> for examples)</td>
</tr>
<tr>
<td>percentage</td>
<td>Indicates whether value percentages should be shown in labels (boolean, see <a href="#graph-examples">various graphs</a> for examples)</td>
</tr>
<tr>
<td>stacked</td>
<td>Depending on the graph type, indicates stacking of multiple columns in the same graph (boolean, see <a href="#graph-examples">various graphs</a> for examples)</td>
</tr>
</tbody>
</table>
<!-- | hidden | Array of columns that should not be visualized in the final graph | -->
<p>The following chart restrictions apply:</p>
<ul>
<li>Up to 50 columns on one graph must be supported.</li>
<li>Chart types are always the same for every column in the graph.</li>
<li>The <code>bar</code> chart type and <code>stacked</code> option are always used together.</li>
<li><code>percentage</code> is always used with the <code>area</code> graph.<!-- * Graphs with every chart type _should_ be able to zoom into the same chart type with the same columns (names and types). -->
<!-- * `y_scaled` is only used with exactly 2 `line` columns -->
</li>
</ul>
<h3><a class="anchor" href="#chart-zooming" id="chart-zooming" name="chart-zooming"><i class="anchor-icon"></i></a>Chart zooming</h3>
<pre><code><a href='/constructor/statsGraphError'>statsGraphError</a>#bedc9822 error:<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/statsGraph'>statsGraph</a>#8ea464b6 flags:<a href='/type/%23'>#</a> json:<a href='/type/DataJSON'>DataJSON</a> zoom_token:flags.0?<a href='/type/string'>string</a> = <a href='/type/StatsGraph'>StatsGraph</a>;
<a href='/constructor/dataJSON'>dataJSON</a>#7d748d04 data:<a href='/type/string'>string</a> = <a href='/type/DataJSON'>DataJSON</a>;
---functions---
<a href='/method/stats.loadAsyncGraph'>stats.loadAsyncGraph</a>#621d5fa0 flags:<a href='/type/%23'>#</a> token:<a href='/type/string'>string</a> x:flags.0?<a href='/type/long'>long</a> = <a href='/type/StatsGraph'>StatsGraph</a>;</code></pre>
<p>Graphs that support zooming will contain a <code>zoom_token</code> in the <a href="/constructor/statsGraph">statsGraph</a> constructor.<br>
Said token should be then used as <code>token</code> in a new <a href="/method/stats.loadAsyncGraph">stats.loadAsyncGraph</a> call triggered when the user clicks on the label, related to a certain x axis in the graph (see <a href="#graph-examples">graph examples</a>).<br>
The <code>x</code> coordinate of the label should be provided to the <code>x</code> parameter; the method will then return (if available) a more detailed subgraph.<br>
If not enough data is available, a localized <a href="/constructor/statsGraphError">statsGraphError</a> will be returned. </p>
<p>Typical zoom <em>visualization</em> rules: </p>
<ul>
<li>Any <code>percentage</code> graph (even if a <code>zoom_token</code> is not available) =&gt; <a href="#piechart">piechart</a></li>
<li><a href="#line-graph">line graph</a> =&gt; <a href="#line-graph">line graph</a></li>
<li><a href="#step-graph">step graph</a> =&gt; <a href="#step-graph">step graph</a></li>
<li><a href="#bar-graph">bar graph</a> =&gt; <a href="#bar-graph">bar graph</a></li>
<li><a href="#area-graph">area graph</a> =&gt; <a href="#area-graph">area graph</a></li>
</ul>
<h3><a class="anchor" href="#chart-colors" id="chart-colors" name="chart-colors"><i class="anchor-icon"></i></a>Chart colors</h3>
<p>Chart colors can be provided as a color key, followed by the primary color value in hex format: </p>
<pre><code>red#e05356</code></pre>
<p>The color key can be one of <code>red</code>, <code>lightblue</code>, <code>lightgreen</code>, <code>golden</code>, <code>green</code>, <code>orange</code>, <code>blue</code>, <code>indigo</code>.<br>
Apps can choose to use a color value specified by the currently loaded theme: for example, the <a href="https://github.com/DrKLO/Telegram/blob/dceccae0b74576d092fb3b2accaffded2c0b5f63/TMessagesProj/src/main/java/org/telegram/ui/Charts/data/ChartData.java#L81">android app</a> uses <code>statisticChartLine_*</code> themekeys for each of the color keys, check out the <a href="https://github.com/DrKLO/Telegram/tree/master/TMessagesProj/src/main/assets">assets directory</a> for a bunch of default themes with various colors for channel statistics. </p>
<p>However, the server may also choose to return just a plain color value in hex format: </p>
<pre><code>#e05356</code></pre>
<p>In this case, the <code>dark</code> flag of the <a href="/method/stats.getBroadcastStats">stats.getBroadcastStats</a> method can be used to choose the palette of returned colors.</p>
<h2><a class="anchor" href="#graph-examples" id="graph-examples" name="graph-examples"><i class="anchor-icon"></i></a>Graph examples</h2>
<h3><a class="anchor" href="#line-graph" id="line-graph" name="line-graph"><i class="anchor-icon"></i></a>Line graph</h3>
<p>Simple single line graph</p>
<h3><a class="anchor" href="#step-graph" id="step-graph" name="step-graph"><i class="anchor-icon"></i></a>Step graph</h3>
<p>Step graph, always "stacked" (to indicate multiple lines)</p>
<h3><a class="anchor" href="#bar-graph" id="bar-graph" name="bar-graph"><i class="anchor-icon"></i></a>Bar graph</h3>
<p>Bar graph with multiple lines, always "stacked" (to indicate actual stacked bars, biggest bars first)</p>
<h3><a class="anchor" href="#area-graph" id="area-graph" name="area-graph"><i class="anchor-icon"></i></a>Area graph</h3>
<p>Mixed bar/line graph, always "stacked" (to indicate actual stacked bars, biggest bars first)</p>
<h3><a class="anchor" href="#piechart" id="piechart" name="piechart"><i class="anchor-icon"></i></a>Piechart</h3>
<p>Piechart, typically obtained only when zooming into percentage graphs</p></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="/">Platform</a></h5>
<ul>
<li><a href="/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script src="/js/jquery.min.js?1"></script>
<script src="/js/bootstrap.min.js?1"></script>
<script>window.initDevPageNav&&initDevPageNav();
backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

View file

@ -0,0 +1,205 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Mobile Protocol: Detailed Description (v.1.0, DEPRECATED)</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="This document describes MTProto v.1.0, its status is DEPRECATED.
For information on encryption used in up-to-date Telegram…">
<meta property="og:title" content="Mobile Protocol: Detailed Description (v.1.0, DEPRECATED)">
<meta property="og:image" content="https://core.telegram.org/file/811140187/1/sfBQV3Trp80/3a3c48bad836b853ed">
<meta property="og:description" content="This document describes MTProto v.1.0, its status is DEPRECATED.
For information on encryption used in up-to-date Telegram…">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class="active"><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/mtproto" >Mobile Protocol</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/mtproto/description_v1" >Mobile Protocol: Detailed Description (v.1.0…</a></li></ul></div>
<h1 id="dev_page_title">Mobile Protocol: Detailed Description (v.1.0, DEPRECATED)</h1>
<div id="dev_page_content"><blockquote>
<p>This document describes MTProto <strong>v.1.0</strong>, its status is <strong>DEPRECATED</strong>.
For information on encryption used in up-to-date Telegram clients, kindly see <a href="/mtproto/description">this document</a>.</p>
</blockquote>
<p>Prior to a message (or a multipart message) being transmitted over a network using a transport protocol, it is encrypted in a certain way, and an external header is added at the top of the message which is: a 64-bit key identifier (that uniquely identifies an authorization key for the server as well as the user) and a 128-bit message key. </p>
<p>A user key together with the message key define an actual 256-bit key and a 256-bit initialization vector, which is what encrypts the message using AES-256 encryption with infinite garble extension (IGE). Note that the initial part of the message to be encrypted contains variable data (session, message ID, sequence number, server salt) that obviously influences the message key (and thus the AES key and iv). The message key is defined as the 128 lower-order bits of the SHA1 of the message body (including session, message ID, etc.) Multipart messages are encrypted as a single message. </p>
<div><a href="/file/811140187/1/sfBQV3Trp80/3a3c48bad836b853ed">
<img src="/file/811140187/1/sfBQV3Trp80/3a3c48bad836b853ed" alt="MTProto server-client encryption, cloud chats" class="dev_page_image">
</a></div>
<h3><a class="anchor" href="#terminology" id="terminology" name="terminology"><i class="anchor-icon"></i></a>Terminology</h3>
<h4><a class="anchor" href="#authorization-key" id="authorization-key" name="authorization-key"><i class="anchor-icon"></i></a>Authorization Key</h4>
<p>a 2048-bit key shared by the client device and the server, created upon user registration directly on the client device be exchanging Diffie-Hellman keys, and never transmitted over a network. Each authorization key is user-specific. There is nothing that prevents a user from having several keys (that correspond to “permanent sessions” on different devices), and some of these may be locked forever in the event the device is lost. See also <a href="/mtproto/auth_key">Creating an Authorization Key</a>.</p>
<h4><a class="anchor" href="#server-key" id="server-key" name="server-key"><i class="anchor-icon"></i></a>Server Key</h4>
<p>a 2048-bit RSA key used by the server digitally to sign its own messages while registration is underway and the authorization key is being generated. The application has a built-in public server key which can be used to verify a signature but cannot be used to sign messages. A private server key is stored on the server and changed very infrequently.</p>
<h4><a class="anchor" href="#key-identifier" id="key-identifier" name="key-identifier"><i class="anchor-icon"></i></a>Key Identifier</h4>
<p>The 64 lower-order bits of the SHA1 hash of the authorization key are used to indicate which particular key was used to encrypt a message. Keys must be uniquely defined by the 64 lower-order bits of their SHA1, and in the event of a collision, an authorization key is regenerated. A zero key identifier means that encryption is not used which is permissible for a limited set of message types used during registration to generate an authorization key based on a Diffie-Hellman exchange.</p>
<h4><a class="anchor" href="#session" id="session" name="session"><i class="anchor-icon"></i></a>Session</h4>
<p>a (random) 64-bit number generated by the client to distinguish between individual sessions (for example, between different instances of the application, created with the same authorization key). The session in conjunction with the key identifier corresponds to an application instance. The server can maintain session state. <em>Under no circumstances can a message meant for one session be sent into a different session</em>. The server may unilaterally forget any client sessions; clients should be able to handle this. </p>
<h4><a class="anchor" href="#server-salt" id="server-salt" name="server-salt"><i class="anchor-icon"></i></a>Server Salt</h4>
<p>a (random) 64-bit number periodically (say, every 24 hours) changed (separately for each session) at the request of the server. All subsequent messages must contain the new salt (although, messages with the old salt are still accepted for a further 300 seconds). Required to protect against replay attacks and certain tricks associated with adjusting the client clock to a moment in the distant future.</p>
<h4><a class="anchor" href="#message-identifier-msg-id" id="message-identifier-msg-id" name="message-identifier-msg-id"><i class="anchor-icon"></i></a>Message Identifier (msg_id)</h4>
<p>a (time-dependent) 64-bit number used uniquely to identify a message within a session. Client message identifiers are divisible by 4, server message identifiers modulo 4 yield 1 if the message is a response to a client message, and 3 otherwise. Client message identifiers must increase monotonically (within a single session), the same as server message identifiers, and must approximately equal unixtime*2^32. This way, a message identifier points to the approximate moment in time the message was created. A message is rejected over 300 seconds after it is created or 30 seconds before it is created (this is needed to protect from replay attacks). In this situation, it must be re-sent with a different identifier (or placed in a container with a higher identifier). The identifier of a message container must be strictly greater than those of its nested messages.</p>
<p><strong>Important</strong>: to counter replay-attacks the lower 32 bits of <strong>msg_id</strong> passed by the client must not be empty and must present a fractional part of the time point when the message was created. At some point in the nearest future the server will start ignoring messages, in which the lower 32 bits of <strong>msg_id</strong> contain too many zeroes.</p>
<h4><a class="anchor" href="#content-related-message" id="content-related-message" name="content-related-message"><i class="anchor-icon"></i></a>Content-related Message</h4>
<p>A message requiring an explicit acknowledgment. These include all the user and many service messages, virtually all with the exception of containers and acknowledgments. </p>
<h4><a class="anchor" href="#message-sequence-number-msg-seqno" id="message-sequence-number-msg-seqno" name="message-sequence-number-msg-seqno"><i class="anchor-icon"></i></a>Message Sequence Number (msg_seqno)</h4>
<p>a 32-bit number equal to twice the number of “content-related” messages (those requiring acknowledgment, and in particular those that are not containers) created by the sender prior to this message and subsequently incremented by one if the current message is a content-related message. A container is always generated after its entire contents; therefore, its sequence number is greater than or equal to the sequence numbers of the messages contained in it.</p>
<h4><a class="anchor" href="#message-key" id="message-key" name="message-key"><i class="anchor-icon"></i></a>Message Key</h4>
<p>The lower-order 128 bits of the SHA1 hash of the part of the message to be encrypted (including the internal header and excluding the alignment bytes).</p>
<h4><a class="anchor" href="#internal-cryptographic-header" id="internal-cryptographic-header" name="internal-cryptographic-header"><i class="anchor-icon"></i></a>Internal (cryptographic) Header</h4>
<p>A header (16 bytes) added before a message or a container before it is all encrypted together. Consists of the server salt (64 bits) and the session (64 bits).</p>
<h4><a class="anchor" href="#external-cryptographic-header" id="external-cryptographic-header" name="external-cryptographic-header"><i class="anchor-icon"></i></a>External (cryptographic) Header</h4>
<p>A header (24 bytes) added before an encrypted message or a container. Consists of a key identifier (64 bits) and a message key (128 bits).</p>
<h4><a class="anchor" href="#payload" id="payload" name="payload"><i class="anchor-icon"></i></a>Payload</h4>
<p>External header + encrypted message or container.</p>
<h3><a class="anchor" href="#defining-aes-key-and-initialization-vector" id="defining-aes-key-and-initialization-vector" name="defining-aes-key-and-initialization-vector"><i class="anchor-icon"></i></a>Defining AES Key and Initialization Vector</h3>
<p>The 2048-bit authorization key (auth_key) and the 128-bit message key (msg_key) are used to compute a 256-bit AES key (aes_key) and a 256-bit initialization vector (aes_iv) which are subsequently used to encrypt the part of the message to be encrypted (i. e. everything with the exception of the external header which is added later) with AES-256 in infinite garble extension (IGE) mode.</p>
<p>The algorithm for computing aes_key and aes_iv from auth_key and msg_key is as follows:</p>
<ul>
<li>msg_key = substr (SHA1 (plaintext), 4, 16);</li>
<li>sha1_a = SHA1 (msg_key + substr (auth_key, x, 32));</li>
<li>sha1_b = SHA1 (substr (auth_key, 32+x, 16) + msg_key + substr (auth_key, 48+x, 16));</li>
<li>sha1_с = SHA1 (substr (auth_key, 64+x, 32) + msg_key);</li>
<li>sha1_d = SHA1 (msg_key + substr (auth_key, 96+x, 32));</li>
<li>aes_key = substr (sha1_a, 0, 8) + substr (sha1_b, 8, 12) + substr (sha1_c, 4, 12);</li>
<li>aes_iv = substr (sha1_a, 8, 12) + substr (sha1_b, 0, 8) + substr (sha1_c, 16, 4) + substr (sha1_d, 0, 8);</li>
</ul>
<p>where x = 0 for messages from client to server and x = 8 for those from server to client.</p>
<p>The lower-order 1024 bits of auth_key are not involved in the computation. They may (together with the remaining bits or separately) be used on the client device to encrypt the local copy of the data received from the server. The 512 lower-order bits of auth_key are not stored on the server; therefore, if the client device uses them to encrypt local data and the user loses the key or the password, data decryption of local data is impossible (even if data from the server could be obtained).</p>
<p>When AES is used to encrypt a block of data of a length not divisible by 16 bytes, the data is padded with random bytes to the smallest length divisible by 16 bytes immediately prior to being encrypted.</p>
<h3><a class="anchor" href="#important-tests" id="important-tests" name="important-tests"><i class="anchor-icon"></i></a>Important Tests</h3>
<p>When an encrypted message is received, it <em>must</em> be checked that msg_key is <em>in fact</em> equal to the 128 lower-order bits of the SHA1 hash of the previously encrypted portion, and that msg_id has even parity for messages from client to server, and odd parity for messages from server to client.</p>
<p>In addition, the identifiers (msg_id) of the last N messages received from the other side must be stored, and if a message comes in with msg_id lower than all or equal to any of the stored values, the message is to be ignored. Otherwise, the new message msg_id is added to the set, and, if the number of stored msg_id values is greater than N, the oldest (i. e. the lowest) is forgotten.</p>
<p>In addition, msg_id values that belong over 30 seconds in the future or over 300 seconds in the past are to be ignored. This is especially important for the server. The client would also find this useful (to protect from a replay attack), but only if it is certain of its time (for example, if its time has been synchronized with that of the server).</p>
<p>Certain client-to-server service messages containing data sent by the client to the server (for example, msg_id of a recent client query) may, nonetheless, be processed on the client even if the time appears to be “incorrect”. This is especially true of messages to change server_salt and notifications of invalid client time. See <a href="/mtproto/service_messages">Mobile Protocol: Service Messages</a>.</p>
<h3><a class="anchor" href="#storing-an-authorization-key-on-a-client-device" id="storing-an-authorization-key-on-a-client-device" name="storing-an-authorization-key-on-a-client-device"><i class="anchor-icon"></i></a>Storing an Authorization Key on a Client Device</h3>
<p>It may be suggested to users concerned with security that they password protect the authorization key in approximately the same way as in ssh. This is accomplished by adding the SHA1 of the key to the front of the key, following which the entire string is encrypted using AES in CBC mode and a key equal to the users (text) password. When the user inputs the password, the stored protected password is decrypted and verified by being compared with SHA1. From the users standpoint, this is practically the same as using an application or a website password.</p>
<h3><a class="anchor" href="#unencrypted-messages" id="unencrypted-messages" name="unencrypted-messages"><i class="anchor-icon"></i></a>Unencrypted Messages</h3>
<p>Special plain-text messages may be used to create an authorization key as well as to perform a time synchronization. They begin with auth_key_id = 0 (64 bits) which means that there is no auth_key. This is followed directly by the message body in serialized format without internal or external headers. A message identifier (64 bits) and body length in bytes (32 bytes) are added before the message body.</p>
<p>Only a very limited number of messages of special types can be transmitted as plain text. </p>
<h3><a class="anchor" href="#schematic-presentation-of-messages" id="schematic-presentation-of-messages" name="schematic-presentation-of-messages"><i class="anchor-icon"></i></a>Schematic Presentation of Messages</h3>
<h4><a class="anchor" href="#encrypted-message" id="encrypted-message" name="encrypted-message"><i class="anchor-icon"></i></a>Encrypted Message</h4>
<table class="table"><tr>
<td><a href="#key-identifier"><strong>auth_key_id</strong></a><br>int64</td>
<td><a href="#message-key"><strong>msg_key</strong></a><br>int128</td>
<td><a href="#encrypted-message-encrypted-data"><strong>encrypted_data</strong></a><br>bytes</td>
</tr></table>
<h4><a class="anchor" href="#encrypted-message-encrypted-data" id="encrypted-message-encrypted-data" name="encrypted-message-encrypted-data"><i class="anchor-icon"></i></a>Encrypted Message: <em>encrypted_data</em></h4>
<p>Contains the cypher text for the following data:</p>
<table class="table"><tr>
<td><a href="#server-salt"><strong>salt</strong></a><br>int64</td>
<td><a href="#session"><strong>session_id</strong></a><br>int64</td>
<td><a href="#message-identifier-msg-id"><strong>message_id</strong></a><br>int64</td>
<td><a href="#message-sequence-number-msg-seqno"><strong>seq_no</strong></a><br>int32</td>
<td><strong>message_data_length</strong><br>int32</td>
<td><strong>message_data</strong><br>bytes</td>
<td><strong>padding</strong> 0..15<br>bytes</td>
</tr></table>
<h4><a class="anchor" href="#unencrypted-message" id="unencrypted-message" name="unencrypted-message"><i class="anchor-icon"></i></a>Unencrypted Message</h4>
<table class="table"><tr>
<td><a href="#key-identifier"><strong>auth_key_id</strong></a> = <code>0</code><br>int64</td>
<td><a href="#message-identifier-msg-id"><strong>message_id</strong></a><br>int64</td>
<td><strong>message_data_length</strong><br>int32</td>
<td><strong>message_data</strong><br>bytes</td>
</tr></table>
<h3><a class="anchor" href="#creating-an-authorization-key" id="creating-an-authorization-key" name="creating-an-authorization-key"><i class="anchor-icon"></i></a>Creating an Authorization Key</h3>
<p>An authorization key is normally created once for every user during the application installation process immediately prior to registration. Registration itself, in actuality, occurs after the authorization key is created. However, a user may be prompted to complete the registration form while the authorization key is being generated in the background. Intervals between user key strokes may be used as a source of entropy in the generation of high-quality random numbers required for the creation of an authorization key.</p>
<p>See <a href="/mtproto/auth_key">Creating an Authorization Key</a>.</p>
<p>During the creation of the authorization key, the client obtains its server salt (to be used with the new key for all communication in the near future). The client then creates an encrypted session using the newly generated key, and subsequent communication occurs within that session (including the transmission of the user's registration information and phone number validation) unless the client creates a new session. The client is free to create new or additional sessions at any time by choosing a new random session_id.</p></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="/">Platform</a></h5>
<ul>
<li><a href="/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script>backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View file

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Nope</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="Deprecated old docs. This was definitely not the droid you were looking for.">
<meta property="og:title" content="Nope">
<meta property="og:image" content="">
<meta property="og:description" content="Deprecated old docs. This was definitely not the droid you were looking for.">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class="active"><a href="/api">API</a></li>
<li class=""><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/api" >API</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/api/geochats" >Nope</a></li></ul></div>
<h1 id="dev_page_title">Nope</h1>
<div id="dev_page_content"><p>Deprecated old docs. This was definitely not the droid you were looking for.</p></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="//core.telegram.org/">Platform</a></h5>
<ul>
<li><a href="//core.telegram.org/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="//core.telegram.org/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script>backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

View file

@ -1,115 +0,0 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Page not found</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="">
<meta property="og:title" content="Page not found">
<meta property="og:image" content="">
<meta property="og:description" content="">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class=""><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"></div>
<h1 id="dev_page_title">Page not found</h1>
<div id="dev_page_content">The page has not been saved</div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="//core.telegram.org/">Platform</a></h5>
<ul>
<li><a href="//core.telegram.org/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="//core.telegram.org/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script>backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

View file

@ -1,149 +0,0 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>decryptedMessageActionSetMessageTTL</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="Setting of a message lifetime after reading.">
<meta property="og:title" content="decryptedMessageActionSetMessageTTL">
<meta property="og:image" content="">
<meta property="og:description" content="Setting of a message lifetime after reading.">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class=""><a href="/mtproto">Protocol</a></li>
<li class="active"><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/api" >API</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/schema" >TL-schema</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/constructor/decryptedMessageActionSetMessageTTL" >decryptedMessageActionSetMessageTTL</a></li></ul></div>
<h1 id="dev_page_title">decryptedMessageActionSetMessageTTL</h1>
<div id="dev_page_content"><p>Setting of a message lifetime after reading.</p>
<p>Upon receiving such message the client shall start deleting of all messages of an encrypted chat <strong>ttl_seconds</strong> seconds after the messages were read by user.</p>
<p><div class="clearfix">
<ul class="dev_layer_select slightly-pull-right nav nav-pills">
<li class="dropdown">
<a class="dropdown-toggle" onclick="return dropdownClick(this, event)" href="#">Layer 137 <b class="caret"></b></a>
<ul class="dropdown-menu">
<li><a href="?layer=1">1 &ndash; Base layer</a></li><li><a href="?layer=2">2 &ndash; New userpic notifications</a></li><li><a href="?layer=3">3 &ndash; Send message can trigger link change</a></li><li><a href="?layer=4">4 &ndash; Check-in chats</a></li><li><a href="?layer=5">5 &ndash; Localized SMS, localized notifications</a></li><li><a href="?layer=6">6 &ndash; Foursquare integration</a></li><li><a href="?layer=7">7 &ndash; Added wallPaperSolid</a></li><li><a href="?layer=8">8 &ndash; Added end-to-end encryption</a></li><li><a href="?layer=9">9 &ndash; Improved big files upload perfomance</a></li><li><a href="?layer=10">10 &ndash; Improved chat participants updates</a></li><li><a href="?layer=11">11 &ndash; Improved secret chats</a></li><li><a href="?layer=12">12 &ndash; New dynamic support</a></li><li><a href="?layer=13">13 &ndash; Audio, video MIME; contacts import retry; new secret actions</a></li><li><a href="?layer=14">14 &ndash; Notify settings sync, blacklist sync</a></li><li><a href="?layer=15">15 &ndash; Modified getHistory offset behaviour</a></li><li><a href="?layer=16">16 &ndash; Split sendCode into 2 parts</a></li><li><a href="?layer=17">17 &ndash; Added custom typing, introduced message flags</a></li><li><a href="?layer=18">18 &ndash; Added usernames</a></li><li><a href="?layer=23">23 &ndash; Stickers for secret chats</a></li><li><a href="?layer=105">105 &ndash; Scheduled messages, Cloud themes</a></li><li><a href="?layer=108">108 &ndash; Login with QR code</a></li><li><a href="?layer=109">109 &ndash; Polls v2</a></li><li><a href="?layer=110">110 &ndash; People Nearby 2.0, Bank card entity</a></li><li><a href="?layer=111">111 &ndash; Folders, Broadcast Stats</a></li><li><a href="?layer=112">112 &ndash; Old featured stickers, generic dice, poll timer, poll solution</a></li><li><a href="?layer=113">113 &ndash; PSA</a></li><li><a href="?layer=114">114 &ndash; Video thumbs for GIFs</a></li><li><a href="?layer=115">115 &ndash; Peek Channel Invite</a></li><li><a href="?layer=116">116 &ndash; Group Stats, Profile Videos</a></li><li><a href="?layer=117">117 &ndash; WebRTC Phone Calls</a></li><li><a href="?layer=118">118 &ndash; Callback with 2FA, Countries list</a></li><li><a href="?layer=119">119 &ndash; Comments in channels, Threads, Anonymous Admins</a></li><li><a href="?layer=120">120 &ndash; Multipins, Message Stats, GeoLive v2</a></li><li><a href="?layer=121">121 &ndash; SVG-based Outlines for Stickers</a></li><li><a href="?layer=122">122 &ndash; Voice Chats</a></li><li><a href="?layer=123">123 &ndash; Voice Chat improvements</a></li><li><a href="?layer=124">124 &ndash; Expiring Invite links</a></li><li><a href="?layer=125">125 &ndash; Voice Chats in Broadcasts</a></li><li><a href="?layer=126">126 &ndash; Ban channels in channels</a></li><li><a href="?layer=127">127 &ndash; Payments in channels</a></li><li><a href="?layer=128">128 &ndash; Microthumbs for User/Chat profile photos</a></li><li><a href="?layer=129">129 &ndash; Video Chats</a></li><li><a href="?layer=130">130 &ndash; Custom placeholder for bot reply keyboards</a></li><li><a href="?layer=131">131 &ndash; Reset 2FA Password after a week</a></li><li><a href="?layer=132">132 &ndash; Chat themes</a></li><li><a href="?layer=133">133 &ndash; 64-bit IDs for User/Chat</a></li><li><a href="?layer=137"><strong>137 &ndash; reactions</strong></a></li>
<li class="divider"></li>
<li><a href="/api/layers">More...</a></li>
</ul>
</li>
</ul>
</div>
<pre class="page_scheme"><code>===8===
<a href="/constructor/decryptedMessageActionSetMessageTTL" class="current_page_link" >decryptedMessageActionSetMessageTTL</a>#a1733aec ttl_seconds:<a href="/type/int" >int</a> = <a href="/type/DecryptedMessageAction" >DecryptedMessageAction</a>;</code></pre></p>
<h3><a class="anchor" href="#parameters" id="parameters" name="parameters"><i class="anchor-icon"></i></a>Parameters</h3>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th style="text-align: center;">Type</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>ttl_seconds</strong></td>
<td style="text-align: center;"><a href="/type/int">int</a></td>
<td>Lifetime in seconds</td>
</tr>
</tbody>
</table>
<h3><a class="anchor" href="#type" id="type" name="type"><i class="anchor-icon"></i></a>Type</h3>
<p><a href="/type/DecryptedMessageAction">DecryptedMessageAction</a></p></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="//core.telegram.org/">Platform</a></h5>
<ul>
<li><a href="//core.telegram.org/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="//core.telegram.org/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script>backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

View file

@ -1,251 +0,0 @@
<!DOCTYPE html>
<html class="">
<head>
<meta charset="utf-8">
<title>Formal description of TL combinators</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="description" content="Formal declaration of TL combinators
Main article: Formal description of TL. See also TL Language.
Combinators in TL are…">
<meta property="og:title" content="Formal description of TL combinators">
<meta property="og:image" content="">
<meta property="og:description" content="Formal declaration of TL combinators
Main article: Formal description of TL. See also TL Language.
Combinators in TL are…">
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
<link href="/css/telegram.css?215" rel="stylesheet" media="screen">
<style>
</style>
</head>
<body class="preload">
<div class="dev_page_wrap">
<div class="dev_page_head navbar navbar-static-top navbar-tg">
<div class="navbar-inner">
<div class="container clearfix">
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
<ul class="nav navbar-nav">
<li><a href="//telegram.org/">Home</a></li>
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
<li class=""><a href="/api">API</a></li>
<li class="active"><a href="/mtproto">Protocol</a></li>
<li class=""><a href="/schema">Schema</a></li>
</ul>
</div>
</div>
</div>
<div class="container clearfix">
<div class="dev_page">
<div id="dev_page_content_wrap" class=" ">
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/mtproto" >Mobile Protocol</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/mtproto/TL-combinators" >Formal description of TL combinators</a></li></ul></div>
<h1 id="dev_page_title">Formal description of TL combinators</h1>
<div id="dev_page_content"><p><a href="/mtproto/TL-combinators">Formal declaration of TL combinators</a></p>
<p>Main article: <a href="TL-formal">Formal description of TL</a>. See also <a href="TL">TL Language</a>.</p>
<p>Combinators in TL are declared as follows:</p>
<div class="richcode">
<p><em>combinator-decl</em> ::= <em>full-combinator-id</em> { <em>opt-args</em> } { <em>args</em> } <code>=</code> <em>result-type</em> <code>;</code><br>
<em>full-combinator-id</em> ::= <em>lc-ident-full</em> | <code>_</code><br>
<em>combinator-id</em> ::= <em>lc-ident-ns</em> | <code>_</code><br>
<em>opt-args</em> ::= <code>{</code> <em>var-ident</em> { <em>var-ident</em> } : [<em>excl-mark</em>] <em>type-expr</em> <code>}</code><br>
<em>args</em> ::= <em>var-ident-opt</em> <code>:</code> [ <em>conditional-arg-def</em> ] [ <code>!</code> ] <em>type-term</em><br>
<em>args</em> ::= [ <em>var-ident-opt</em> <code>:</code> ] [ <em>multiplicity</em> <code>*</code>] <code>[</code> { <em>args</em> } <code>]</code><br>
<em>args</em> ::= <code>(</code> <em>var-ident-opt</em> { <em>var-ident-opt</em> } <code>:</code> [<code>!</code>] <em>type-term</em> <code>)</code><br>
<em>args</em> ::= [ <code>!</code> ] <em>type-term</em><br>
<em>multiplicity</em> ::= <em>nat-term</em><br>
<em>var-ident-opt</em> ::= <em>var-ident</em> | <code>_</code><br>
<em>conditional-arg-def</em> ::= <em>var-ident</em> [ <code>.</code> <em>nat-const</em> ] <code>?</code><br>
<em>result-type</em> ::= <em>boxed-type-ident</em> { <em>subexpr</em> }<br>
<em>result-type</em> ::= <em>boxed-type-ident</em> <code>&lt;</code> <em>subexpr</em> { <code>,</code> <em>subexpr</em> } <code>&gt;</code> </p>
</div>
<p>We shall clarify what all this means.</p>
<ul>
<li>
<p>A combinator identifier is either an identifier starting with a lowercase Latin letter (<em>lc-ident</em>), or a namespace identifier (also <em>lc-ident</em>) followed by a period and another <em>lc-ident</em>. Therefore, <code>cons</code> and <code>lists.get</code> are valid combinator identifiers.</p>
</li>
<li>
<p>A combinator has a <em>name</em>, also known as a <em>number</em> (not to be confused with the <em>designation</em>) -- a 32-bit number that unambiguously determines it. It is either calculated automatically (see below) or it is explicitly assigned in the declaration. To do this, a hash mark (<code>#</code>) and exactly 8 hexadecimal digits -- the combinators name -- are added to the identifier of the combinator being defined.</p>
</li>
<li>
<p>A combinators declaration begins with its identifier, to which its name (separated by a hash mark) may have been added.</p>
</li>
<li>
<p>After the combinator identifier comes the main part of the declaration, which consists of declarations of <em>fields</em> (or <em>variables</em>), including an indication of their <em>types</em>.</p>
</li>
<li>
<p>First come declarations of optional fields (of which there may be several or none at all). Then there are the declarations of the required fields (there may not be any of these either).</p>
</li>
<li>
<p>Any identifier that begins with an uppercase or lowercase letter and which does not contain references to a namespace can be a field (variable) identifier. Using <em>uc-ident</em> for identifiers of variable types and <em>lc-indent</em> for other variables is good practice. </p>
</li>
<li>
<p>Next a combinator declaration contains the equals sign (<code>=</code>) and the result type (it may be composite or appearing for the first time). The result type may be polymorphic and/or dependent; any fields of the defined constructors fields of type <code>Type</code> or <code>#</code> may be returned (as subexpressions).</p>
</li>
<li>
<p>A combinator declaration is terminated with a semicolon.</p>
</li>
</ul>
<p>In what follows, a constructors <em>fields</em>, <em>variables</em>, and <em>arguments</em> mean the same thing.</p>
<h3><a class="anchor" href="#optional-field-declarations" id="optional-field-declarations" name="optional-field-declarations"><i class="anchor-icon"></i></a>Optional field declarations</h3>
<ul>
<li>
<p>These have the form <code>{</code> <em>field_1</em> ... <em>field_k</em> <code>:</code> <em>type-expr</em> <code>}</code>, where <em>field_i</em> is a variable (field) identifier that is unique within the scope of the combinator declaration, and <em>type-expr</em> is a type shared by all of the fields. </p>
</li>
<li>
<p>If <em>k&gt;1</em>, this entry is functionally equivalent to <code>{</code> <em>field_1</em> <code>:</code> <em>type-expr</em> <code>}</code> ... <code>{</code> <em>field_k</em> <code>:</code> <em>type-expr</em> <code>}</code>. </p>
</li>
<li>
<p>All optional fields must be explicitly named (using <code>_</code> instead of <em>field_i</em> is not allowed).</p>
</li>
<li>
<p>Moreover, at present the names of all optional fields must share the combinators result type (possibly more than once) and themselves be of type <code>#</code> (i,e., <code>nat</code>) or <code>Type</code>. Therefore, if the exact result type is known, it is possible to determine the values of all of the combinators implicit parameters (possibly obtaining a contradiction of the form <code>2=3</code> in doing so, which means that the combinator is not allowed in the context).</p>
</li>
</ul>
<h3><a class="anchor" href="#required-field-declarations" id="required-field-declarations" name="required-field-declarations"><i class="anchor-icon"></i></a>Required field declarations</h3>
<ul>
<li>
<p>These may have the form <code>(</code> <em>field_1</em> ... <em>field_k</em> <code>:</code> <em>type-expr</em> <code>)</code>, similar to an optional field declaration, but with parentheses. This entry is equivalent to <code>(</code> <em>field_1</em> <code>:</code> <em>type-expr</em> <code>)</code> ... <code>(</code> <em>field_k</em> : <em>type-expr</em> <code>)</code>, where the fields are defined one at a time.</p>
</li>
<li>
<p>The underscore sign (<code>_</code>) can be used as names of one or more fields (<em>field_i</em>), indicating that the field is anonymous (the exact name is unimportant).</p>
</li>
<li>
<p>One field may be declared without outer parentheses, like this: <em>field_id</em> <code>:</code> <em>type-expr</em>. Here, however, if <em>type-expr</em> is a complex type, parentheses may be necessary around <em>type-expr</em> (this is reflected in BNF).</p>
</li>
<li>
<p>Furthermore, one anonymous field may be declared using a <em>type-expr</em> entry, functionally equivalent to <code>_</code> <code>:</code> <em>type-expr</em>.</p>
</li>
<li>
<p>Required field declarations follow one after another, separated by spaces (by any number of whitespace symbols, to be more precise).</p>
</li>
<li>
<p>The declared fields type (<em>type-expr</em>) may use the declared combinators previously defined variables (fields) as subexpressions (i.e. parameter values). For example:</p>
<p>nil {X:Type} = List X;
cons {X:Type} hd:X tl:(list X) = List X;
typed_list (X:Type) (l : list X) = TypedList;</p>
</li>
</ul>
<h3><a class="anchor" href="#repetitions" id="repetitions" name="repetitions"><i class="anchor-icon"></i></a>Repetitions</h3>
<ul>
<li>
<p>These may only exist among required parameters. They have the form [ <em>field-id</em> <code>:</code> ] [ <em>multiplicity</em> <code>*</code> ] <code>[</code> <em>args</em> <code>]</code>, where <em>args</em> has the same format as the combinators declaration of (several) required fields, except that all of the enclosing combinators previously declared fields may be used in the argument types.</p>
</li>
<li>
<p>The name of a field of an enclosing combinator that receives a repetition as a value may be specified (<em>field-id</em>), or bypassed, which is equivalent to using the underscore sign as a <em>field-id</em>.</p>
</li>
<li>
<p>The <em>multiplicity</em> field is an expression of the type <code>#</code> (<code>nat</code>), which can be a real constant, the name of a preceding field of type <code>#</code>, or an expression in the form <code>(</code> <em>c</em> <code>+</code> <em>v</em> <code>)</code>, where <em>c</em> is a real constant and <em>v</em> is the name of a field of type <code>#</code>. The sense of the <em>multiplicity</em> field is to provide the length of the (repetition) vector, each element of which consists of values of the types enumerated in <em>args</em>.</p>
</li>
<li>
<p>The <em>multiplicity</em> field may be bypassed. In this case, the last preceding parameter of type <code>#</code> from the enclosing combinator is used (it must be).</p>
</li>
<li>
<p>Functionally, the repetition <em>field-id</em> <code>:</code> <em>multiplicity</em> <code>*</code> <code>[</code> <em>args</em> <code>]</code> is equivalent to the declaration of the single field <code>(</code> <em>field-id</em> <code>:</code> <code>%Tuple</code> <code>%AuxType</code> <em>multiplicity</em> <code>)</code>, where <code>aux_type</code> is an auxiliary type with a new name defined as <code>aux_type *args* = AuxType</code>. If any of the enclosing types fields are used within <em>args</em>, they are added to the auxiliary constructor <code>aux_type</code> and to its <code>AuxType</code> result type as the first (optional) parameters. </p>
</li>
<li>
<p>If <em>args</em> consists of one anonymous field of type <em>some-type</em>, then <em>some-type</em> can be used directly instead of <code>%AuxType</code>.</p>
</li>
<li>
<p>If during implementation the repetitions are rewritten as indicated above, it is logical to use instead of <code>aux_type</code> and <code>AuxType</code>, some identifiers that contain the name of the outer combinator being defined and the repetitions index number inside its definition.</p>
</li>
</ul>
<p>Example:</p>
<pre><code>matrix {m n : #} a : m* [ n* [ double ] ] = Matrix m n;</code></pre>
<p>is functionally equivalent to</p>
<pre><code>aux_type {n : #} (_ : %Tuple double n) = AuxType n;
matrix {m : #} {n : #} (a : %Tuple %(AuxType n) m) = Matrix m n;</code></pre>
<p>Moreover, the built-in types <code>Tuple</code> and <code>Vector</code> could be defined as:</p>
<pre><code>tnil {X : Type} = Tuple X 0;
tcons {X : Type} {n : #} hd:X tl:%(Tuple X n) = Tuple X (S n);
vector {X : Type} (n : #) (v : %(Tuple X n)) = Vector X;</code></pre>
<p>Actually, the following equivalent entry is considered the definition of <code>Vector</code> (i.e. it is specifically this entry that is used to compute the name of the <code>vector</code> constructor and its partial applications):</p>
<pre><code>vector {t : Type} # [ t ] = Vector t;</code></pre>
<p>If we expand it using <code>Tuple</code>, we obtain the previous definition exactly.</p>
<h3><a class="anchor" href="#conditional-fields" id="conditional-fields" name="conditional-fields"><i class="anchor-icon"></i></a>Conditional fields</h3>
<p>The construction </p>
<div class="richcode">
<p><em>args</em> ::= <em>var-ident-opt</em> <code>:</code> [ <em>conditional-arg-def</em> ] [ <code>!</code> ] <em>type-term</em><br>
<em>conditional-arg-def</em> ::= <em>var-ident</em> [ <code>.</code> <em>nat-const</em> ] <code>?</code> </p>
</div>
<p>permits assigning fields which are only present if the value of a preceding mandatory or optional field of type <code>#</code> is not null (or if its chosen bit is not zero if the special binary bit-selection operator <code>.</code> is applied).
Example:</p>
<div class="richcode">
<p>user {fields:#} id:int first_name:(fields.0?string) last_name:(fields.1?string) friends:(fields.2?%(Vector int)) = User fields;<br>
get_users req_fields:# ids:%(Vector int) = Vector %(User req_fields) </p>
</div></div>
</div>
</div>
</div>
<div class="footer_wrap">
<div class="footer_columns_wrap footer_desktop">
<div class="footer_column footer_column_telegram">
<h5>Telegram</h5>
<div class="footer_telegram_description"></div>
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
</div>
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
<ul>
<li><a href="//telegram.org/faq">FAQ</a></li>
<li><a href="//telegram.org/blog">Blog</a></li>
<li><a href="//telegram.org/jobs">Jobs</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
<ul>
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
<li><a href="//telegram.org/dl/android">Android</a></li>
<li><a href="//telegram.org/dl/wp">Windows Phone</a></li>
</ul>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
<ul>
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
<li><a href="//macos.telegram.org/">macOS</a></li>
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
</ul>
</div>
<div class="footer_column footer_column_platform">
<h5><a href="//core.telegram.org/">Platform</a></h5>
<ul>
<li><a href="//core.telegram.org/api">API</a></li>
<li><a href="//translations.telegram.org/">Translations</a></li>
<li><a href="//instantview.telegram.org/">Instant View</a></li>
</ul>
</div>
</div>
<div class="footer_columns_wrap footer_mobile">
<div class="footer_column">
<h5><a href="//telegram.org/faq">About</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/blog">Blog</a></h5>
</div>
<div class="footer_column">
<h5><a href="//telegram.org/apps">Apps</a></h5>
</div>
<div class="footer_column">
<h5><a href="//core.telegram.org/">Platform</a></h5>
</div>
<div class="footer_column">
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
</div>
</div>
</div>
</div>
<script src="/js/main.js?43"></script>
<script>backToTopInit("Go up");
removePreloadInit();
</script>
</body>
</html>

File diff suppressed because it is too large Load diff