[gnome-software/wip/temp/ubuntu-xenial-rebased: 326/329] Various updates to conflicts in the rebase
- From: Iain Lane <iainl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-software/wip/temp/ubuntu-xenial-rebased: 326/329] Various updates to conflicts in the rebase
- Date: Fri, 29 Apr 2016 14:12:46 +0000 (UTC)
commit f7a86832a7039b5c57714f7f030f16c8c9409a5e
Author: William Hua <william hua canonical com>
Date: Wed Apr 20 07:33:40 2016 -0400
Various updates to conflicts in the rebase
Sorry for the messy history
src/gs-plugin.h | 1 +
src/plugins/Makefile.am | 37 ++++++++++
src/plugins/gs-plugin-appstream.c | 5 +-
src/plugins/gs-plugin-apt.cc | 24 +++++--
src/plugins/gs-plugin-dummy.c | 8 +-
src/plugins/gs-plugin-packagekit.c | 141 +++++++++++++++++++++++-------------
src/plugins/gs-plugin-snappy.c | 54 ++------------
7 files changed, 158 insertions(+), 112 deletions(-)
---
diff --git a/src/gs-plugin.h b/src/gs-plugin.h
index 94438f2..668692b 100644
--- a/src/gs-plugin.h
+++ b/src/gs-plugin.h
@@ -137,6 +137,7 @@ typedef enum {
GS_PLUGIN_REFRESH_FLAGS_NONE = 0,
GS_PLUGIN_REFRESH_FLAGS_METADATA = 1 << 0,
GS_PLUGIN_REFRESH_FLAGS_PAYLOAD = 1 << 1,
+ GS_PLUGIN_REFRESH_FLAGS_UI = 1 << 2,
/*< private >*/
GS_PLUGIN_REFRESH_FLAGS_LAST
} GsPluginRefreshFlags;
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index 8cf7e21..61d37a4 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -145,6 +145,27 @@ libgs_plugin_odrs_la_LDFLAGS = -module -avoid-version
libgs_plugin_odrs_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
endif
+if HAVE_APT
+ubuntu-unity-launcher-proxy.c ubuntu-unity-launcher-proxy.h: com.canonical.Unity.Launcher.xml Makefile
+ $(AM_V_GEN) gdbus-codegen --interface-prefix com.canonical.Unity.Launcher \
+ --generate-c-code ubuntu-unity-launcher-proxy \
+ --c-namespace UbuntuUnity \
+ --annotate 'com.canonical.Unity.Launcher' \
+ org.gtk.GDBus.C.Name \
+ Launcher \
+ $<
+
+CLEANFILES = ubuntu-unity-launcher-proxy.h ubuntu-unity-launcher-proxy.c
+
+libgs_plugin_apt_la_SOURCES = \
+ ubuntu-unity-launcher-proxy.c \
+ ubuntu-unity-launcher-proxy.h \
+ gs-plugin-apt.cc
+libgs_plugin_apt_la_LIBADD = $(GS_PLUGIN_LIBS) -lapt-pkg
+libgs_plugin_apt_la_LDFLAGS = -module -avoid-version
+libgs_plugin_apt_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+endif
+
libgs_plugin_moduleset_la_SOURCES = \
gs-moduleset.c \
gs-moduleset.h \
@@ -271,6 +292,22 @@ libgs_plugin_packagekit_proxy_la_LIBADD = $(GS_PLUGIN_LIBS)
libgs_plugin_packagekit_proxy_la_LDFLAGS = -module -avoid-version
libgs_plugin_packagekit_proxy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+libgs_plugin_snappy_la_SOURCES = \
+ gs-plugin-snappy.c \
+ gs-ubuntuone.h \
+ gs-ubuntuone.c \
+ gs-ubuntuone-dialog.h \
+ gs-ubuntuone-dialog.c \
+ gs-ubuntu-snapd.h \
+ gs-ubuntu-snapd.c
+libgs_plugin_snappy_la_LIBADD = \
+ $(GS_PLUGIN_LIBS) \
+ $(SOUP_LIBS) \
+ $(JSON_GLIB_LIBS) \
+ $(LIBSECRET_LIBS)
+libgs_plugin_snappy_la_LDFLAGS = -module -avoid-version
+libgs_plugin_snappy_la_CFLAGS = $(GS_PLUGIN_CFLAGS) $(WARN_CFLAGS)
+
check_PROGRAMS = \
gs-self-test
diff --git a/src/plugins/gs-plugin-appstream.c b/src/plugins/gs-plugin-appstream.c
index ffc9241..f7b0b8b 100644
--- a/src/plugins/gs-plugin-appstream.c
+++ b/src/plugins/gs-plugin-appstream.c
@@ -67,8 +67,6 @@ gs_plugin_appstream_store_changed_cb (AsStore *store, GsPlugin *plugin)
gs_plugin_updates_changed (plugin);
}
-static gboolean gs_plugin_appstream_startup (GsPlugin *plugin, GError **error);
-
gboolean
gs_plugin_refresh (GsPlugin *plugin,
guint cache_age,
@@ -77,8 +75,7 @@ gs_plugin_refresh (GsPlugin *plugin,
GError **error)
{
if (flags & GS_PLUGIN_REFRESH_FLAGS_UI) {
- plugin->priv->done_init = FALSE;
- gs_plugin_appstream_startup (plugin, NULL);
+ gs_plugin_setup (plugin, cancellable, error);
gs_plugin_updates_changed (plugin);
}
diff --git a/src/plugins/gs-plugin-apt.cc b/src/plugins/gs-plugin-apt.cc
index bd4e8a6..9434cad 100644
--- a/src/plugins/gs-plugin-apt.cc
+++ b/src/plugins/gs-plugin-apt.cc
@@ -627,14 +627,26 @@ gs_plugin_refine (GsPlugin *plugin,
} else {
gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
}
- if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_PROVENANCE) != 0 && info->is_official) {
- gs_app_set_provenance (app, TRUE);
+ }
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_ORIGIN) != 0) {
+ g_autofree gchar *origin = get_origin (info);
+ gs_app_set_origin (app, origin);
+ gs_app_set_origin_ui (app, info->origin);
+ }
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_SIZE) != 0 && gs_app_get_size (app) == 0) {
+ gs_app_set_size (app, info->installed_size);
+ }
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_VERSION) != 0) {
+ if (info->installed_version != NULL) {
+ gs_app_set_version (app, info->installed_version);
+ } else {
+ gs_app_set_version (app, info->update_version);
}
- if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE) != 0 && info->is_open_source) {
- gs_app_set_licence (app, "@LicenseRef-ubuntu", GS_APP_QUALITY_HIGHEST);
+ if (info->update_version != NULL) {
+ gs_app_set_update_version (app, info->update_version);
}
}
- if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENCE) != 0 && is_open_source(info)) {
+ if ((flags & GS_PLUGIN_REFINE_FLAGS_REQUIRE_LICENSE) != 0 && is_open_source(info)) {
gs_app_set_license (app, GS_APP_QUALITY_LOWEST, "@LicenseRef-free=" LICENSE_URL);
}
@@ -953,7 +965,7 @@ gs_plugin_refresh (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
- if ((flags & GS_PLUGIN_REFRESH_FLAGS_UPDATES) == 0)
+ if ((flags & GS_PLUGIN_REFRESH_FLAGS_PAYLOAD) == 0)
return TRUE;
if (!aptd_transaction (plugin, "UpdateCache", NULL, NULL, NULL, error))
diff --git a/src/plugins/gs-plugin-dummy.c b/src/plugins/gs-plugin-dummy.c
index 059e590..d9159be 100644
--- a/src/plugins/gs-plugin-dummy.c
+++ b/src/plugins/gs-plugin-dummy.c
@@ -284,10 +284,10 @@ gs_plugin_app_install (GsPlugin *plugin,
}
/**
- * gs_plugin_app_update:
+ * gs_plugin_update_app:
*/
gboolean
-gs_plugin_app_update (GsPlugin *plugin,
+gs_plugin_update_app (GsPlugin *plugin,
GsApp *app,
GCancellable *cancellable,
GError **error)
@@ -521,10 +521,10 @@ gs_plugin_app_upgrade_trigger (GsPlugin *plugin, GsApp *app,
}
/**
- * gs_plugin_offline_update_cancel:
+ * gs_plugin_update_cancel:
*/
gboolean
-gs_plugin_offline_update_cancel (GsPlugin *plugin, GsApp *app,
+gs_plugin_update_cancel (GsPlugin *plugin, GsApp *app,
GCancellable *cancellable, GError **error)
{
return TRUE;
diff --git a/src/plugins/gs-plugin-packagekit.c b/src/plugins/gs-plugin-packagekit.c
index 98e7f5f..2ce848d 100644
--- a/src/plugins/gs-plugin-packagekit.c
+++ b/src/plugins/gs-plugin-packagekit.c
@@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
*
- * Copyright (C) 2013-2016 Richard Hughes <richard hughsie com>
+ * Copyright (C) 2013 Richard Hughes <richard hughsie com>
*
* Licensed under the GNU General Public License Version 2
*
@@ -152,7 +152,7 @@ gs_plugin_add_installed (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
+ if (results == NULL)
return FALSE;
/* add results */
@@ -168,6 +168,7 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
GCancellable *cancellable,
GError **error)
{
+ GList *installed = NULL;
GList *l;
GsApp *app;
GsApp *app_tmp;
@@ -175,7 +176,6 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
ProgressData data;
const gchar *id;
gboolean ret = TRUE;
- g_autoptr(GsAppList) installed = NULL;
g_autoptr(PkResults) results = NULL;
g_autoptr(AsProfileTask) ptask = NULL;
@@ -194,14 +194,16 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
- return FALSE;
+ if (results == NULL) {
+ ret = FALSE;
+ goto out;
+ }
ret = gs_plugin_packagekit_add_results (plugin,
&installed,
results,
error);
if (!ret)
- return FALSE;
+ goto out;
for (l = installed; l != NULL; l = l->next) {
g_auto(GStrv) split = NULL;
app = GS_APP (l->data);
@@ -216,7 +218,9 @@ gs_plugin_add_sources_related (GsPlugin *plugin,
}
}
}
- return TRUE;
+out:
+ gs_plugin_list_free (installed);
+ return ret;
}
/**
@@ -251,7 +255,7 @@ gs_plugin_add_sources (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
+ if (results == NULL)
return FALSE;
hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
array = pk_results_get_repo_detail_array (results);
@@ -260,7 +264,7 @@ gs_plugin_add_sources (GsPlugin *plugin,
rd = g_ptr_array_index (array, i);
id = pk_repo_detail_get_id (rd);
app = gs_app_new (id);
- gs_app_set_management_plugin (app, plugin->name);
+ gs_app_set_management_plugin (app, "PackageKit");
gs_app_set_kind (app, AS_APP_KIND_SOURCE);
gs_app_set_state (app, AS_APP_STATE_INSTALLED);
gs_app_set_name (app,
@@ -304,9 +308,7 @@ gs_plugin_app_source_enable (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
- return FALSE;
- return TRUE;
+ return results != NULL;
}
/**
@@ -323,8 +325,8 @@ gs_plugin_app_install (GsPlugin *plugin,
ProgressData data;
const gchar *package_id;
guint i, j;
- g_autoptr(PkResults) results = NULL;
- g_autoptr(GPtrArray) array_package_ids = NULL;
+ g_autoptr(PkError) error_code = NULL;
+ g_autofree gchar *local_filename = NULL;
g_auto(GStrv) package_ids = NULL;
g_autoptr(GPtrArray) array_package_ids = NULL;
g_autoptr(PkResults) results = NULL;
@@ -334,7 +336,7 @@ gs_plugin_app_install (GsPlugin *plugin,
data.ptask = NULL;
/* only process this app if was created by this plugin */
- if (g_strcmp0 (gs_app_get_management_plugin (app), plugin->name) != 0)
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") != 0)
return TRUE;
/* we enable the repo */
@@ -363,16 +365,13 @@ gs_plugin_app_install (GsPlugin *plugin,
gs_plugin_packagekit_progress_cb, &data,
error);
if (results == NULL) {
- gs_plugin_packagekit_convert_gerror (error);
- gs_app_set_state_recover (app);
+ gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
return FALSE;
}
- /* state is known */
- gs_app_set_state (app, AS_APP_STATE_INSTALLED);
-
/* no longer valid */
gs_app_clear_source_ids (app);
+ gs_app_set_state (app, AS_APP_STATE_INSTALLED);
return TRUE;
}
@@ -432,19 +431,11 @@ gs_plugin_app_install (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (results == NULL) {
- gs_plugin_packagekit_convert_gerror (error);
- gs_app_set_state_recover (app);
+ if (results == NULL)
return FALSE;
- }
-
- /* state is known */
- gs_app_set_state (app, AS_APP_STATE_INSTALLED);
-
break;
case AS_APP_STATE_AVAILABLE_LOCAL:
- package_id = gs_app_get_metadata_item (app, "packagekit::local-filename");
- if (package_id == NULL) {
+ if (gs_app_get_local_file (app) == NULL) {
g_set_error_literal (error,
GS_PLUGIN_ERROR,
GS_PLUGIN_ERROR_NOT_SUPPORTED,
@@ -459,17 +450,11 @@ gs_plugin_app_install (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (results == NULL) {
- gs_plugin_packagekit_convert_gerror (error);
- gs_app_set_state_recover (app);
+ if (results == NULL)
return FALSE;
- }
-
- /* state is known */
- gs_app_set_state (app, AS_APP_STATE_INSTALLED);
/* get the new icon from the package */
- gs_app_set_metadata (app, "packagekit::local-filename", NULL);
+ gs_app_set_local_file (app, NULL);
gs_app_set_icon (app, NULL);
gs_app_set_pixbuf (app, NULL);
break;
@@ -485,6 +470,17 @@ gs_plugin_app_install (GsPlugin *plugin,
/* no longer valid */
gs_app_clear_source_ids (app);
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to install package: %s, %s",
+ pk_error_enum_to_string (pk_error_get_code (error_code)),
+ pk_error_get_details (error_code));
+ return FALSE;
+ }
return TRUE;
}
@@ -512,9 +508,7 @@ gs_plugin_app_source_disable (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
- return FALSE;
- return TRUE;
+ return results != NULL;
}
/**
@@ -567,6 +561,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
ProgressData data;
guint i;
guint cnt = 0;
+ g_autoptr(PkError) error_code = NULL;
g_autoptr(PkResults) results = NULL;
g_auto(GStrv) package_ids = NULL;
@@ -575,7 +570,7 @@ gs_plugin_app_remove (GsPlugin *plugin,
data.ptask = NULL;
/* only process this app if was created by this plugin */
- if (g_strcmp0 (gs_app_get_management_plugin (app), plugin->name) != 0)
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") != 0)
return TRUE;
/* remove repo and all apps in it */
@@ -616,21 +611,65 @@ gs_plugin_app_remove (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error)) {
- gs_app_set_state_recover (app);
+ if (results == NULL)
return FALSE;
- }
-
- /* state is not known: we don't know if we can re-install this app */
- gs_app_set_state (app, AS_APP_STATE_UNKNOWN);
/* no longer valid */
gs_app_clear_source_ids (app);
+ /* check error code */
+ error_code = pk_results_get_error_code (results);
+ if (error_code != NULL) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "failed to remove package: %s, %s",
+ pk_error_enum_to_string (pk_error_get_code (error_code)),
+ pk_error_get_details (error_code));
+ return FALSE;
+ }
return TRUE;
}
/**
+ * gs_plugin_app_upgrade_download:
+ */
+gboolean
+gs_plugin_app_upgrade_download (GsPlugin *plugin,
+ GsApp *app,
+ GCancellable *cancellable,
+ GError **error)
+{
+ ProgressData data;
+ g_autoptr(PkResults) results = NULL;
+
+ data.app = app;
+ data.plugin = plugin;
+ data.ptask = NULL;
+
+ /* check is distro-upgrade */
+ if (gs_app_get_kind (app) != AS_APP_KIND_OS_UPGRADE) {
+ g_set_error (error,
+ GS_PLUGIN_ERROR,
+ GS_PLUGIN_ERROR_FAILED,
+ "app %s is not a distro upgrade",
+ gs_app_get_id (app));
+ return FALSE;
+ }
+
+ /* ask PK to download enough packages to upgrade the system */
+ gs_app_set_state (app, AS_APP_STATE_INSTALLING);
+ results = pk_client_upgrade_system (PK_CLIENT (plugin->priv->task),
+ pk_bitfield_from_enums (PK_TRANSACTION_FLAG_ENUM_ONLY_DOWNLOAD,
-1),
+ gs_app_get_version (app),
+ PK_UPGRADE_KIND_ENUM_COMPLETE,
+ cancellable,
+ gs_plugin_packagekit_progress_cb, &data,
+ error);
+ return results != NULL;
+}
+
+/**
* gs_plugin_add_search_files:
*/
gboolean
@@ -659,7 +698,7 @@ gs_plugin_add_search_files (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
+ if (results == NULL)
return FALSE;
/* add results */
@@ -695,7 +734,7 @@ gs_plugin_add_search_what_provides (GsPlugin *plugin,
cancellable,
gs_plugin_packagekit_progress_cb, &data,
error);
- if (!gs_plugin_packagekit_results_valid (results, error))
+ if (results == NULL)
return FALSE;
/* add results */
@@ -712,7 +751,7 @@ gs_plugin_launch (GsPlugin *plugin,
GError **error)
{
/* only process this app if was created by this plugin */
- if (g_strcmp0 (gs_app_get_management_plugin (app), plugin->name) != 0)
+ if (g_strcmp0 (gs_app_get_management_plugin (app), "PackageKit") != 0)
return TRUE;
return gs_plugin_app_launch (plugin, app, error);
}
diff --git a/src/plugins/gs-plugin-snappy.c b/src/plugins/gs-plugin-snappy.c
index 76035f8..87fb1aa 100644
--- a/src/plugins/gs-plugin-snappy.c
+++ b/src/plugins/gs-plugin-snappy.c
@@ -230,53 +230,13 @@ get_apps (GsPlugin *plugin, const gchar *sources, gchar **search_terms, GList **
app = gs_app_new (id);
gs_app_set_management_plugin (app, "snappy");
- gs_app_set_kind (app, GS_APP_KIND_NORMAL);
- status = json_object_get_string_member (package, "status");
- if (g_strcmp0 (status, "installed") == 0 || g_strcmp0 (status, "active") == 0) {
- const gchar *update_available;
-
- update_available = json_object_has_member (package, "update_available") ?
json_object_get_string_member (package, "update_available") : NULL;
- if (update_available)
- gs_app_set_state (app, AS_APP_STATE_UPDATABLE);
- else
- gs_app_set_state (app, AS_APP_STATE_INSTALLED);
- size = json_object_get_int_member (package, "installed_size");
- }
- else if (g_strcmp0 (status, "removed") == 0) {
- // A removed app is only available if it can be downloaded (it might have been
sideloaded)
- size = json_object_get_int_member (package, "download_size");
- if (size > 0)
- gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
- } else if (g_strcmp0 (status, "not installed") == 0) {
- gs_app_set_state (app, AS_APP_STATE_AVAILABLE);
- size = json_object_get_int_member (package, "download_size");
- }
- gs_app_set_name (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package,
"name"));
- gs_app_set_summary (app, GS_APP_QUALITY_HIGHEST, json_object_get_string_member (package,
"description"));
- gs_app_set_version (app, json_object_get_string_member (package, "version"));
- gs_app_set_provenance (app, TRUE);
- gs_app_set_id_kind (app, AS_ID_KIND_DESKTOP);
- icon_url = json_object_get_string_member (package, "icon");
- if (g_str_has_prefix (icon_url, "/")) {
- g_autoptr(GSocket) icon_socket = NULL;
- g_autofree gchar *icon_response = NULL;
- gsize icon_response_length;
-
- icon_socket = open_snapd_socket (NULL);
- if (icon_socket && send_snapd_request (icon_socket, "GET", icon_url, NULL, NULL,
NULL, NULL, &icon_response, &icon_response_length, NULL)) {
- g_autoptr(GdkPixbufLoader) loader = NULL;
-
- loader = gdk_pixbuf_loader_new ();
- gdk_pixbuf_loader_write (loader, (guchar *) icon_response,
icon_response_length, NULL);
- gdk_pixbuf_loader_close (loader, NULL);
- icon_pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader));
- }
- else
- g_printerr ("Failed to get icon\n");
- }
- else {
- g_autoptr(SoupMessage) message = NULL;
- g_autoptr(GdkPixbufLoader) loader = NULL;
+ gs_app_set_origin (app, _("Ubuntu Snappy Store"));
+ gs_app_set_kind (app, AS_APP_KIND_DESKTOP);
+ gs_app_add_quirk (app, AS_APP_QUIRK_NOT_REVIEWABLE);
+ gs_app_add_quirk (app, AS_APP_QUIRK_NOT_LAUNCHABLE);
+ refine_app (plugin, app, package);
+ gs_plugin_add_app (list, app);
+ }
g_list_free (snaps);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]