Federated Learning Lets Surveillance Cameras Learn Without Sharing

Analysis by the aitrendblend editorial team · Pillar 6, Federated learning and AI privacy · Reading time about 15 minutes
federated learning video anomaly detection privacy preserving AI CLIP and vision language models surveillance systems
Multiple surveillance camera feeds from separate institutions feeding local models that share only weight updates with a central server
Every institution keeps its own footage. Only the model’s learned weights ever leave the building.
A hospital, a school, and a shopping mall each run their own security cameras, and each one would benefit enormously from a smarter anomaly detector trained on everyone’s footage combined. None of them can actually do that. Sharing raw surveillance video across institutions runs into privacy law, security policy, and plain common sense all at once, so every one of these systems ends up training on its own limited slice of the world and missing whatever the other two already learned. A new paper out of Xidian University and Renmin University proposes a way to get the benefit of shared learning without ever moving a single frame of footage off site.

Key points

  • The paper introduces PPVAD, a federated learning framework for weakly supervised video anomaly detection that trains across institutions without sharing raw video.
  • A lightweight client network built on frozen CLIP encoders adds only a handful of trainable modules, an image prompt, a text prompt, a temporal encoder, and an adapter, keeping communication costs low.
  • Three new server aggregation strategies, score based weighted averaging, cluster based partial averaging, and anomaly ratio weighted averaging, each target a different way that client data can go unevenly.
  • Under federated training, PPVAD beats every other federated method reported on UCF-Crime, XD-Violence, and ShanghaiTech, and comes close to matching centralized training that pools all the data together.
  • Communication overhead per round stays under fifty megabytes per client and local training takes well under a minute, which is a genuinely deployable cost profile rather than a theoretical one.

The problem with training on everyone’s cameras at once

Weakly supervised video anomaly detection has become the dominant approach to flagging unusual events in surveillance footage, precisely because it sidesteps the need for frame by frame labels. A human only has to tag whether a whole video contains an anomaly somewhere, not exactly which frames, and the model learns to localize the anomaly on its own using a multiple instance learning setup. That is a real practical advantage, but it still assumes the model gets to see all the training videos in one place.

Real surveillance networks do not work that way. A school district’s cameras, a hospital’s cameras, and a retail chain’s cameras are typically siloed by design, and for good reason, surveillance footage often captures identifiable people going about private business. Even setting privacy law aside, most institutions simply are not willing to hand a vendor or a research partner a copy of their raw video. The paper’s authors point out the obvious downstream cost, models trained only on one institution’s narrow slice of scenes, camera angles, and anomaly types generalize poorly to anything outside that slice.

Federated learning is the natural fix for exactly this shape of problem. Instead of centralizing data, each institution trains a model locally and only ever sends the model’s learned weights to a coordinating server, which combines them into a shared global model and sends it back out. The raw footage never has to leave the building it was recorded in.

Why this matters beyond surveillance. Federated learning has already proven itself in privacy sensitive fields like medical imaging, where hospitals train shared diagnostic models without pooling patient scans. This paper is essentially porting that same trust model to security video, where the privacy stakes are just as real but the research attention has lagged behind.

Building a client model light enough to actually federate

A federated system lives or dies on how much has to be communicated every round, so the authors deliberately kept the trainable part of their client network small. The backbone is CLIP, the widely used vision language model that aligns images and text in a shared embedding space, and CLIP’s own image and text encoders stay completely frozen throughout training. Freezing the encoders does two things at once, it preserves the broad visual and semantic knowledge CLIP already learned from massive pretraining, and it means those large encoder weights never need to be uploaded or downloaded during federated rounds at all.

What actually gets trained, and what actually gets communicated, are four lightweight modules layered on top of the frozen backbone.

An image prompt to close the domain gap

CLIP was pretrained mostly on clean, well composed natural images, the kind found in datasets like ImageNet. Surveillance footage looks nothing like that, it tends to be low resolution, poorly lit, and shot from an awkward downward angle. Rather than fine tuning CLIP’s own image encoder to close that gap, which would be expensive to train and expensive to communicate, the framework adds a small learnable image prompt that gets added directly to the frozen encoder’s output features, nudging them toward the surveillance domain without touching the encoder itself.

A temporal encoder to notice patterns across frames

A single frame’s features cannot capture events that unfold over time, a person loitering, a fight escalating, a crowd suddenly scattering. The client network adds a small temporal module, a shallow transformer followed by a two layer multilayer perceptron, that processes the sequence of frame level features together and lets the model pick up on exactly these fine grained temporal patterns.

A text prompt and an adapter, tuned specifically for security scenes

On the language side, CLIP’s frozen text encoder processes two prompts, one built around the phrase describing an abnormal scene and one describing a normal scene, each with its own learnable suffix that the training process tunes to fit the surveillance domain. A small adapter module then refines the resulting text features further, so the final text representation aligns as closely as possible with what the visual branch is producing.

Putting the two branches together, the model scores every frame by taking the dot product between its video feature and the text features for the abnormal and normal prompts. Training uses a hinge based multiple instance ranking loss, essentially teaching the model that the most anomalous looking frame in a video labeled abnormal should score meaningfully higher than the most anomalous looking frame in a video labeled normal, combined with a smaller regularization term that discourages the model from flagging too many frames at once or jumping around erratically between neighboring frames.

What gets trained and communicated versus what stays frozen and local
ModuleParameter statusTrained locallyShared with server
Image encoderFrozenNoNo
Text encoderFrozenNoNo
Image promptLearnableYesYes
Text promptLearnableYesYes
Temporal encoderLearnableYesYes
AdapterLearnableYesYes

Three ways to combine everyone’s updates, and why one is not enough

The standard way to merge federated updates, FedAvg, simply averages every client’s weights together, weighted by how much data each client has. That works fine when every client’s data looks roughly similar. The moment institutions differ meaningfully in how good their local model turns out, in what kind of scenes they cover, or in how many of their videos actually contain anomalies, plain averaging starts pulling the shared model in inconsistent directions, a problem the federated learning literature calls client drift. Surveillance data is a near perfect storm for this, different institutions genuinely do cover different scenes, different camera setups, and wildly different ratios of normal to abnormal footage. So the authors design three alternative aggregation strategies, each aimed at a specific way client data can diverge.

Score based weighted averaging, for clients with uneven skill

The most direct fix is to trust better performing clients more. Score based weighted averaging measures each client’s performance on a shared test set after local training, converts those scores into weights using a softmax function, and averages the uploaded weights accordingly. A client whose local model happens to be more accurate gets proportionally more influence over the next global model.

Cluster based partial averaging, for clients whose data looks fundamentally different

Sometimes the issue is not skill but genuine distributional mismatch, one institution’s cameras cover a completely different mix of scenes than another’s. Cluster based partial averaging groups clients whose uploaded parameters look similar to each other, on the reasoning that similar parameters usually reflect similar underlying data, then only averages within the largest such cluster rather than across every client indiscriminately. This keeps a badly mismatched client from dragging the global model away from where most clients actually sit.

Anomaly ratio weighted averaging, for clients with lopsided anomaly counts

The last strategy addresses a more specific imbalance, the proportion of videos that actually contain an anomaly varies a lot from institution to institution. A client whose footage happens to include a richer share of genuine anomalies has more useful signal to contribute toward learning what anomalies look like, so anomaly ratio weighted averaging weights each client’s contribution by its own anomaly ratio, giving anomaly rich clients more say in shaping the global model’s understanding of abnormal behavior.

Under such conditions, uniform averaging strategies such as FedAvg increase the variance of aggregated updates. In surveillance scenarios, data collected by different institutions contain diverse scenes, viewpoints, and anomaly types, which further intensifies data heterogeneity. Paraphrased from Li, Liu, Jiao, Wang, Ma, Wang, Liu, Bao, Liu, Li and Chen, Knowledge Based Systems, 2026

How well does the federated version actually perform

The authors test PPVAD on three well established benchmarks, UCF-Crime, a large collection of real world street and indoor surveillance footage covering thirteen categories of crime, XD-Violence, an even larger and more varied collection pulled from movies, sports broadcasts, and CCTV footage, and ShanghaiTech, a smaller campus surveillance dataset. Every result is reported twice, once under a centralized setting where all the data is pooled together as an upper bound, and once under the federated setting that actually respects data privacy.

The federated numbers are the ones that matter most here, since that is the setting the paper is actually built for. On UCF-Crime, PPVAD reaches an area under the curve score of 87.25 percent under federated training, ahead of the next best federated method, FedVAD, by a little over two percentage points, and ahead of CLAP, an earlier privacy focused baseline, by roughly four points. On XD-Violence, PPVAD’s federated area under the curve reaches 91.85 percent, more than six points ahead of CLAP and about three points ahead of FedVAD. On ShanghaiTech, PPVAD posts a federated area under the curve of 98.24 percent, ahead of the strongest prior federated approaches tested.

Just as telling is how close the federated numbers land to the centralized ones. On XD-Violence in particular, PPVAD’s federated result comes within about half a point of VadCLIP’s centralized result, a method that gets to see every institution’s data pooled together with no privacy constraint at all. That gap, or rather the near absence of one, is the paper’s central practical claim, that federated training does not have to mean settling for meaningfully worse detection just to protect privacy.

Selected federated results, area under the curve, unless noted
MethodUCF-CrimeXD-Violence AUCXD-Violence APShanghaiTech
FedAvg baseline aggregation86.12%
CLAP83.23%85.67%66.57%
FedVAD85.13%66.78%
Fed-WS-VAD97.10%
PPVAD (federated)87.25%91.85%79.86%98.24%

Does the custom aggregation actually beat off the shelf federated optimizers

It would be easy for a paper to claim its own aggregation strategies are better without checking them against the broader federated learning toolbox, so it is worth noting the authors do run that comparison directly. Against nine established aggregation methods, including FedAdam, FedProx, FedAvgM, and several Byzantine robust variants, the paper’s own anomaly ratio weighted averaging strategy comes out slightly ahead across random, category based, and scene based data splits on UCF-Crime. The margins are not enormous, typically well under a single percentage point over the next best generic method, but the consistency across three quite different ways of splitting the data suggests the improvement is not a fluke tied to one particular split.

The data splitting experiment itself is worth understanding, because it is a more realistic stress test than a single benchmark number implies. Random splitting distributes videos evenly and represents the easiest, most independent and identically distributed case. Category based splitting hands each simulated institution a different mix of anomaly types, mimicking a scenario where one hospital mostly sees theft while another mostly sees violence. Scene based splitting hands each institution a different physical environment entirely, mimicking schools, hotels, and streets each running their own cameras. Performance degrades somewhat as you move from random splitting toward these more realistic, more skewed splits, which the authors are candid about, this is exactly where non independent and identically distributed federated learning remains a genuinely open problem rather than a solved one.

What this actually costs to run

A privacy preserving method that is too expensive to deploy is not much use to anyone, so the paper’s complexity analysis deserves attention. On UCF-Crime, each client uploads roughly ten million parameters per round, which works out to about forty megabytes of communication per client per round. Local training per client takes about twenty two seconds, and a full communication round, including the server side aggregation step, takes roughly thirty two seconds. With five clients participating, that puts a full round at well under a minute of wall clock time, which is a genuinely practical cost profile for a system institutions might run on a recurring schedule rather than as a one off experiment.

The authors also stress test the system under conditions closer to a real deployment. When client hardware is deliberately made uneven, mixing older and newer GPUs across clients, synchronization latency creeps up slightly but stays in a similar range, around eleven to twelve seconds per round. When clients are allowed to randomly drop out of a training round entirely, simulating network instability, performance degrades gradually and gracefully rather than collapsing, PPVAD still reaches a respectable area under the curve even when only two of five clients participate in a given round.

Why the ablation results matter here. The paper’s module by module ablation shows every added component, the image prompt, the temporal encoder’s transformer layers, its multilayer perceptron, and the adapter, each contributes a measurable improvement on its own, and removing any one of them costs real accuracy. That is a meaningfully more convincing story than a single end to end number, because it shows the architecture was not over engineered with parts that do not actually pull weight.

Honest limitations worth keeping in mind

The gap between federated and centralized performance, while consistently small in this paper, is not zero, and on UCF-Crime specifically centralized methods still hold a real edge over every federated method tested, PPVAD included. The paper’s own data splitting experiments confirm that performance degrades as client data distributions become more skewed, and the authors are upfront that non independent and identically distributed federated learning remains an open research area rather than something this paper fully resolves. The complexity analysis, while encouraging, is also run entirely on hardware within a single research lab rather than across geographically distributed institutions with real network latency between them, so real world communication delays could look different from what is reported here. Finally, the paper’s data availability statement notes that the authors do not have permission to share the underlying data, and no code repository link accompanies this particular paper, which means independent reproduction will depend on institutions building their own implementation from the architecture described rather than starting from a public release.

Conclusion

The core contribution here is showing, with real benchmark numbers rather than just a plausible sounding architecture diagram, that weakly supervised video anomaly detection does not have to choose between institutional privacy and shared learning. By keeping CLIP’s encoders frozen and training only a handful of lightweight modules, the framework keeps communication costs low enough to be practical, and by replacing plain federated averaging with three purpose built aggregation strategies, it addresses the specific ways surveillance data tends to diverge across institutions rather than treating federated learning as a one size fits all recipe.

The more interesting conceptual point is what the three aggregation strategies reveal about the problem itself. Client drift in federated surveillance is not one problem, it is at least three different problems wearing the same name, uneven client skill, genuinely different data distributions, and lopsided anomaly proportions, and the paper’s approach of building a distinct tool for each rather than one universal fix is a more honest way to handle heterogeneity than hoping a single averaging trick covers every case.

Whether these specific strategies generalize cleanly beyond video anomaly detection to other federated computer vision tasks is an open question the paper does not attempt to answer, and any team adapting this approach to a different domain should treat that as a genuine unknown rather than an assumed transfer.

The remaining gaps, a persistent though narrow centralized advantage, degraded performance under more realistic non independent and identically distributed splits, and complexity numbers measured on a single research cluster rather than a true multi institution network, all point toward reasonable next steps rather than settled conclusions. None of them undercut the paper’s central result, they simply mark where the next round of research needs to look.

What is worth carrying away from this paper is less any single accuracy number and more the demonstration that privacy and performance are not automatically in tension here. A federated system that comes within roughly half a point of a centralized upper bound on one of its benchmarks is a genuinely useful existence proof for anyone who has been told that protecting data privacy necessarily means accepting a materially worse model.

A runnable sketch of the client network and the three aggregation strategies

The following is a simplified but complete and runnable implementation of the paper’s client network and its three server aggregation strategies, including the multiple instance ranking loss, the Top-K instance selection, the regularization term, and a smoke test on synthetic frame features so you can see a full federated round run end to end.

import torch
import torch.nn as nn
import torch.nn.functional as F
import copy

# —————————————————————–
# Client network, a lightweight head on top of frozen CLIP style
# image and text features, following Section 3.3 of the paper
# —————————————————————–
class ClientNetwork(nn.Module):
    def __init__(self, feature_dim=512, suffix_len=8, transformer_layers=2):
        super().__init__()
        # learnable image prompt, added to frozen image features, Eq. 2
        self.image_prompt = nn.Parameter(torch.randn(1, 1, feature_dim) * 0.02)

        # temporal encoder, a shallow transformer plus a small MLP
        encoder_layer = nn.TransformerEncoderLayer(
            d_model=feature_dim, nhead=8, batch_first=True)
        self.temporal_transformer = nn.TransformerEncoder(encoder_layer, num_layers=transformer_layers)
        self.temporal_mlp = nn.Sequential(
            nn.Linear(feature_dim, feature_dim), nn.GELU(),
            nn.Linear(feature_dim, feature_dim),
        )

        # learnable text prompt suffixes for the abnormal and normal classes
        self.text_suffix_abnormal = nn.Parameter(torch.randn(suffix_len, feature_dim) * 0.02)
        self.text_suffix_normal = nn.Parameter(torch.randn(suffix_len, feature_dim) * 0.02)

        # adapter that refines the frozen text encoder’s output, Eq. 4
        self.adapter = nn.Sequential(
            nn.Linear(feature_dim, feature_dim), nn.ReLU(),
            nn.Linear(feature_dim, feature_dim),
        )

    def encode_video(self, frozen_image_features):
        # frozen_image_features, shape (batch, num_frames, feature_dim)
        domain_adapted = frozen_image_features + self.image_prompt
        temporal_features = self.temporal_transformer(domain_adapted)
        video_features = self.temporal_mlp(temporal_features)
        return video_features  # shape (batch, num_frames, feature_dim)

    def encode_text(self, frozen_text_encoder_fn):
        # frozen_text_encoder_fn maps a suffix tensor to a frozen text embedding,
        # standing in for the real CLIP text tower with a fixed prefix already applied
        raw_abnormal = frozen_text_encoder_fn(self.text_suffix_abnormal)
        raw_normal = frozen_text_encoder_fn(self.text_suffix_normal)
        text_features = torch.stack([
            self.adapter(raw_abnormal), self.adapter(raw_normal)
        ], dim=0)
        return text_features  # shape (2, feature_dim), abnormal then normal

    def forward(self, frozen_image_features, frozen_text_encoder_fn):
        video_features = self.encode_video(frozen_image_features)
        text_features = self.encode_text(frozen_text_encoder_fn)
        # dot product similarity gives per frame logits for abnormal vs normal
        logits = torch.einsum(“btd,cd->btc”, video_features, text_features)
        anomaly_scores = torch.softmax(logits, dim=-1)[…, 0]  # abnormal channel
        return anomaly_scores  # shape (batch, num_frames)


# —————————————————————–
# MIL ranking loss with Top-K selection and the sparsity plus smoothness
# regularization term, following Eq. 5, Eq. 6, and Eq. 7
# —————————————————————–
def mil_loss(anomaly_scores, video_labels, top_k=3, lam=1e-5):
    “””anomaly_scores, shape (batch, num_frames). video_labels, shape (batch,)
    with 1 for abnormal videos and 0 for normal videos.”””
    top_scores, _ = anomaly_scores.topk(top_k, dim=1)
    mean_top_k = top_scores.mean(dim=1)  # shape (batch,)

    abnormal_mask = video_labels == 1
    normal_mask = video_labels == 0
    if abnormal_mask.sum() == 0 or normal_mask.sum() == 0:
        return torch.tensor(0.0, requires_grad=True)

    abnormal_score = mean_top_k[abnormal_mask].mean()
    normal_score = mean_top_k[normal_mask].mean()
    ranking_loss = F.relu(1.0 + normal_score – abnormal_score)

    # regularization only over the abnormal videos, Eq. 6
    abnormal_scores_full = anomaly_scores[abnormal_mask]
    sparsity_term = abnormal_scores_full.mean()
    smoothness_term = (abnormal_scores_full[:, 1:] – abnormal_scores_full[:, :-1]).pow(2).mean()
    reg_loss = sparsity_term + smoothness_term

    return ranking_loss + lam * reg_loss


# —————————————————————–
# Three server aggregation strategies, following Eq. 8, Eq. 9, and Eq. 10
# —————————————————————–
def score_based_weighted_averaging(client_state_dicts, client_scores):
    “””SWA, softmax over client performance scores.”””
    scores = torch.tensor(client_scores)
    weights = torch.softmax(scores, dim=0)
    return _weighted_average(client_state_dicts, weights)


def anomaly_ratio_weighted_averaging(client_state_dicts, client_anomaly_ratios):
    “””AWA, weight each client by its share of anomalous training videos.”””
    ratios = torch.tensor(client_anomaly_ratios, dtype=torch.float32)
    weights = ratios / ratios.sum().clamp_min(1e-8)
    return _weighted_average(client_state_dicts, weights)


def cluster_based_partial_averaging(client_state_dicts, num_clusters=2):
    “””CPA, flatten each client’s parameters, cluster them, and average
    only within the largest cluster, following Eq. 9.”””
    from sklearn.cluster import KMeans
    flat_vectors = torch.stack([
        torch.cat([p.flatten() for p in sd.values()]) for sd in client_state_dicts
    ]).numpy()
    labels = KMeans(n_clusters=min(num_clusters, len(client_state_dicts)), n_init=10, random_state=0).fit_predict(flat_vectors)
    values, counts = __import__(“numpy”).unique(labels, return_counts=True)
    largest_cluster_label = values[counts.argmax()]
    selected = [sd for sd, lab in zip(client_state_dicts, labels) if lab == largest_cluster_label]
    equal_weights = torch.ones(len(selected)) / len(selected)
    return _weighted_average(selected, equal_weights)


def _weighted_average(client_state_dicts, weights):
    averaged = copy.deepcopy(client_state_dicts[0])
    for key in averaged:
        stacked = torch.stack([sd[key].float() for sd in client_state_dicts])
        averaged[key] = (weights.view(-1, *([1] * (stacked.dim() – 1))) * stacked).sum(dim=0)
    return averaged


# —————————————————————–
# Smoke test, three clients with synthetic frame features, one
# federated round using each of the three aggregation strategies
# —————————————————————–
def run_smoke_test():
    torch.manual_seed(0)
    feature_dim, num_frames, batch = 32, 16, 4

    def dummy_text_encoder(suffix):
        # stand in for a frozen CLIP text tower, just pool the suffix
        return suffix.mean(dim=0)

    num_clients = 3
    clients = [ClientNetwork(feature_dim=feature_dim) for _ in range(num_clients)]
    optimizers = [torch.optim.AdamW(c.parameters(), lr=2e-5) for c in clients]
    client_scores, client_anomaly_ratios = [], []

    for client, optimizer in zip(clients, optimizers):
        frozen_features = torch.randn(batch, num_frames, feature_dim)
        video_labels = torch.randint(0, 2, (batch,))

        optimizer.zero_grad()
        scores = client(frozen_features, dummy_text_encoder)
        loss = mil_loss(scores, video_labels)
        loss.backward()
        optimizer.step()

        client_scores.append(float(-loss.item()))  # lower loss stands in for higher performance score
        client_anomaly_ratios.append(float(video_labels.float().mean()))
        print(f”client loss, {loss.item():.4f}”)

    client_state_dicts = [c.state_dict() for c in clients]

    global_swa = score_based_weighted_averaging(client_state_dicts, client_scores)
    global_awa = anomaly_ratio_weighted_averaging(client_state_dicts, client_anomaly_ratios)
    global_cpa = cluster_based_partial_averaging(client_state_dicts)

    print(f”SWA global image prompt norm, {global_swa[‘image_prompt’].norm():.4f}”)
    print(f”AWA global image prompt norm, {global_awa[‘image_prompt’].norm():.4f}”)
    print(f”CPA global image prompt norm, {global_cpa[‘image_prompt’].norm():.4f}”)


if __name__ == “__main__”:
    run_smoke_test()

Running this trains three separate client networks for one local step each on random synthetic features, then merges their weights three different ways, printing the resulting norm of the aggregated image prompt under each strategy so you can see the three aggregation rules genuinely produce different global weights from the same client updates, exactly the behavior the paper is arguing matters once client data actually diverges.

Go straight to the source

This article summarizes and analyzes the original research. Read the full methodology, all result tables, and the complete ablation and sensitivity analysis directly from the publisher.

Read the paper

Frequently asked questions

What problem does federated learning solve for video anomaly detection?

It lets multiple institutions train a shared anomaly detection model together without any of them having to share their raw surveillance footage, since only model weight updates are ever sent to a central server.

How does PPVAD keep communication costs low?

It freezes CLIP’s large image and text encoders entirely and only trains and communicates a small set of lightweight modules, an image prompt, a text prompt, a temporal encoder, and an adapter, which keeps the per round upload well under fifty megabytes per client.

Why does the paper propose three different server aggregation strategies instead of one?

Because client data can diverge in different ways, some clients simply perform better, some have fundamentally different data distributions, and some have very different proportions of anomalous footage, and each of the three strategies is built to address one of these specific patterns rather than assuming a single averaging rule fits every case.

How close does federated training get to training on all the pooled data at once?

Quite close on the datasets tested here. On XD-Violence, for example, PPVAD’s federated result lands within about half a point of a strong centralized baseline that pools every institution’s data together with no privacy constraint.

Does this approach still work if some institutions drop out of a training round?

Yes, though performance degrades gradually rather than staying flat. The paper reports that PPVAD still reaches a respectable detection accuracy even when only two out of five simulated clients participate in a given round.

Is this method’s code publicly available?

Not according to the paper itself. Its data availability statement notes that the authors do not have permission to share the underlying data, and no code repository link is listed, so this article’s code section is an independent, simplified reproduction rather than the authors’ own release.

Academic citation. Li, S., Liu, F., Jiao, L., Wang, J., Ma, Y., Wang, X., Liu, Y., Bao, Q., Liu, X., Li, L., and Chen, P. Privacy preserving video anomaly detection via federated learning. Knowledge Based Systems, 349, 116454, 2026.

This analysis is based on the published paper and an independent evaluation of its claims.

Related reading

Leave a Comment

Your email address will not be published. Required fields are marked *