Exemple #1
0
void FacebookAuth::dataReady()
{
  OAUTH_PREPARE_REPLY
  OAUTH_BAD_STATUS

  QVariantMap data = JSON::parse(raw).toMap();
  QByteArray uid = data.value(LS("id")).toByteArray();
  if (uid.isEmpty())
    return setError("invalid_uid");

  User user;
  user.name     = data.value(LS("name")).toString();
  user.email    = data.value(LS("email")).toString();
  user.link     = data.value(LS("link")).toString();

  QStringList birthday = data.value(LS("birthday")).toString().split(LC('/'));
  if (birthday.size() == 3)
    user.birthday = birthday.at(2) + LC('-') + birthday.at(0) + LC('-') + birthday.at(1);

  QByteArray id = SimpleID::encode(SimpleID::make("facebook:" + uid, SimpleID::UserId));
  AuthCore::state()->add(new AuthStateData(m_state, "facebook", id, data, user));

  log(NodeLog::InfoLevel, "Data is successfully received, id:" + id + ", uid:" + uid);
  deleteLater();
}
Exemple #2
0
/**
 * Add the given header to the header list, overwriting any previous
 * header entries having the same (case-insensitive) key.
 */
static void overwrite_header(struct headers **headers, struct headers *header)
{
    /* find any previous instance of the header (case-insensitive) and delete */
    char *newheader = strdup(header->header);
    struct headers *p = *headers;

    /* lower-case the new header */
    LC(newheader);

    while (1) {
        /* lower-case the old header */
        char *oldheader = strdup(p->header);
        LC(oldheader);

        if (strcmp(newheader, oldheader) == 0) {
            /* delete the old header key and value */
            free(p->header);
            free(p->value);
            p->header = header->header;
            p->value = header->value;
            free(header);
            return;
        }

        if (p->next == *headers)
            break;
        p = p->next;
    }
    /* no match found, append the new header to the end of the list */
    RING_APPEND((*headers), header);
}
Exemple #3
0
bool HtmlFilter::colorValue(QString &value) const
{
  int r = -1;
  int g = -1;
  int b = -1;

  if (value.startsWith(LC('#')) && !HtmlFilterPrivate::get_hex_rgb(value.constData(), value.length(), &r, &g, &b))
    return false;

  if (value.startsWith(LS("rgb(")) ) {
    const QStringList rgb = value.mid(4, value.size() - 5).remove(LC(' ')).split(LC(','));
    if (rgb.size() == 3) {
      r = rgb.at(0).toInt();
      g = rgb.at(1).toInt();
      b = rgb.at(2).toInt();
    }
  }

  if (r == -1 && g == -1 && b == -1)
    return false;

  if (r > 210 && g > 210 && b > 210)
    return false;

  value.sprintf("#%02x%02x%02x", r, g, b);
  return true;
}
Exemple #4
0
/*!
 * Обработка запроса пользователя на создание нового фида.
 *
 * Эта функция вызывается \b post запросом содержащим только имя фида.
 */
FeedReply NodeFeeds::add()
{
  FeedReply reply(Notice::OK);
  const QString &name = m_packet->text();
  if (name.contains(LC('*')) || name.contains(LC('/')) || name.contains(LC(' ')))
    return Notice::BadRequest;

  FeedPtr feed = m_channel->feed(name, false);
  if (!feed) {
    feed = m_channel->feed(name, true, false);
    if (!feed)
      return Notice::InternalError;

    feed->head().acl().add(m_user->id());
    reply.status = FeedStorage::save(feed);
  }
  else
    FeedStorage::clone(feed);

  reply.status = FeedStorage::save(feed);
  if (reply.status == Notice::OK)
    reply.date = feed->head().date();

  return reply;
}
Exemple #5
0
void RegionEU433InitDefaults( InitType_t type )
{
    switch( type )
    {
        case INIT_TYPE_INIT:
        {
            // Channels
            Channels[0] = ( ChannelParams_t ) EU433_LC1;
            Channels[1] = ( ChannelParams_t ) EU433_LC2;
            Channels[2] = ( ChannelParams_t ) EU433_LC3;

            // Initialize the channels default mask
            ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 );
            // Update the channels mask
            RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 1 );
            break;
        }
        case INIT_TYPE_RESTORE:
        {
            // Restore channels default mask
            ChannelsMask[0] |= ChannelsDefaultMask[0];
            break;
        }
        default:
        {
            break;
        }
    }
}
Exemple #6
0
int
widget_memory_draw( void *data )
{
  int x, y;
  char pbuf[36];

  widget_rectangle( LC(0), LR(0), 40 * 8, 16 * 8 + 4, 1 );
  widget_rectangle( LC(0), LR(16) + 2, 320, 1, 7 );

  for( y = 0; y < 16; ++y ) {
    libspectrum_word addr = memaddr + y * 8;

    sprintf( pbuf, "%04X:", addr );
    widget_printstring_right( LC(5) - 4, LR(y), 5, pbuf );

    for( x = 0; x < 8; ++x ) {
      libspectrum_byte b = readbyte_internal( addr + x );

      widget_printchar_fixed( LC(x + 29) / 8, LR(y) / 8, 7 - (y & 1), b );
      sprintf( pbuf + x * 3, "%02X ", b );
    }
    widget_printstring_fixed( LC(5) / 8, LR(y) / 8, 7 - (y & 1), pbuf );
  }

  widget_display_lines( LR(0) / 8, 17 );

  return 0;
}
Exemple #7
0
bool HtmlFilter::cssValue(const QString &property, const QString &tag, const Range &range, QString &value) const
{
  int start = -1;
  int end = range.second;

  forever {
    start = tag.lastIndexOf(property + LC(':'), end);
    if (start == -1 || start < range.first)
      return false;

    if (range.first == start)
      break;

    const QChar c = tag.at(start - 1);
    if (c == LC(' ') || c == LC(';'))
      break;

    end = start - 1;
  }

  start = start + property.size() + 1;
  end = tag.indexOf(';', start);
  if (end == -1)
    end = range.second;

  if (start == end)
    return false;

  value = tag.mid(start, end - start).simplified();
  return true;
}
Exemple #8
0
bool RegionEU433AdrNext( AdrNextParams_t* adrNext, int8_t* drOut, int8_t* txPowOut, uint32_t* adrAckCounter )
{
    bool adrAckReq = false;
    int8_t datarate = adrNext->Datarate;
    int8_t txPower = adrNext->TxPower;
    GetPhyParams_t getPhy;
    PhyParam_t phyParam;

    // Report back the adr ack counter
    *adrAckCounter = adrNext->AdrAckCounter;

    if( adrNext->AdrEnabled == true )
    {
        if( datarate == EU433_TX_MIN_DATARATE )
        {
            *adrAckCounter = 0;
            adrAckReq = false;
        }
        else
        {
            if( adrNext->AdrAckCounter >= EU433_ADR_ACK_LIMIT )
            {
                adrAckReq = true;
                txPower = EU433_MAX_TX_POWER;
            }
            else
            {
                adrAckReq = false;
            }
            if( adrNext->AdrAckCounter >= ( EU433_ADR_ACK_LIMIT + EU433_ADR_ACK_DELAY ) )
            {
                if( ( adrNext->AdrAckCounter % EU433_ADR_ACK_DELAY ) == 1 )
                {
                    // Decrease the datarate
                    getPhy.Attribute = PHY_NEXT_LOWER_TX_DR;
                    getPhy.Datarate = datarate;
                    getPhy.UplinkDwellTime = adrNext->UplinkDwellTime;
                    phyParam = RegionEU433GetPhyParam( &getPhy );
                    datarate = phyParam.Value;

                    if( datarate == EU433_TX_MIN_DATARATE )
                    {
                        // We must set adrAckReq to false as soon as we reach the lowest datarate
                        adrAckReq = false;
                        if( adrNext->UpdateChanMask == true )
                        {
                            // Re-enable default channels
                            ChannelsMask[0] |= LC( 1 ) + LC( 2 ) + LC( 3 );
                        }
                    }
                }
            }
        }
    }

    *drOut = datarate;
    *txPowOut = txPower;
    return adrAckReq;
}
Exemple #9
0
void Game::createBObject(fixedvec pos, fixedvec vel)
{
	Common& common = *this->common;

	BObject& obj = *bobjects.newObjectReuse();
	
	obj.color = rand(LC(NumBloodColours)) + LC(FirstBloodColour);
	obj.pos = pos;
	obj.vel = vel;
}
Exemple #10
0
QStringList ChatUrls::path(const QUrl &url)
{
  QString path = url.path(); // В некоторых случаях путь возвращается без начального /.
  if (path.startsWith(LC('/')))
    path.remove(0, 1);

  if (path.isEmpty())
    return QStringList();

  return path.split(LC('/'), QString::SkipEmptyParts);
}
Exemple #11
0
QUrl ChatUrls::fromLocalFile(const QString &localFile)
{
  QUrl url;
  url.setScheme(LS("file"));
  QString deslashified = QDir::fromNativeSeparators(localFile);

  if (deslashified.length() > 1 && deslashified.at(1) == LC(':') && deslashified.at(0) != LC('/'))
    url.setPath(LC('/') + deslashified);
  else
    url.setPath(deslashified);

  return url;
}
Exemple #12
0
EmoticonData::EmoticonData(const QString &file, const QString &id, const QVariantMap &data)
  : m_hidden(false)
  , m_height(0)
  , m_width(0)
  , m_file(file)
  , m_id(id)
{
  if (data.isEmpty())
    return;

  QVariantList icon = data.value(LS("icon")).toList();
  if (icon.size() < 4)
    return;

  m_file   += LC('/') + icon.at(0).toString();
  m_width  = icon.at(1).toInt();
  m_height = icon.at(2).toInt();
  m_hidden = data.value(LS("hidden"), false).toBool();

  for (int i = 3; i < icon.size(); ++i) {
    const QString text = Qt::escape(icon.at(i).toString());
    if (text.isEmpty())
      continue;

    if (!m_texts.contains(text))
      m_texts.append(text);
  }
}
Exemple #13
0
QString LinksFilter::url(const QString &text, int index, int &last) const
{
  last = text.indexOf(LC(' '), index);
  QString url;
  last == -1 ? url = text.mid(index) : url = text.mid(index, last - index);
  return url;
}
Exemple #14
0
bool FixUrlFilter::filter(QList<HtmlToken> &tokens, int options) const
{
  Q_UNUSED(options)

  QList<HtmlToken> out;
  QString name;
  bool remove = false;

  foreach (const HtmlToken &token, tokens) {
    if (token.type == HtmlToken::StartTag && token.tag == LS("a")) {
      HtmlATag tag(token);
      if (tag.url.startsWith(LS("chat://channel/"))) {
        ClientChannel user = ChatUrls::channel(QUrl(tag.url));
        if (user)
          name = user->name();
      }

      out.append(token);
    }
    else if (!name.isEmpty()) {
      if (name != token.text) {
        out.append(HtmlToken(name));
        out.append(HtmlToken(HtmlToken::Tag, LS("</a>")));
        remove = true;

        if (token.text.startsWith(name))
          out.append(HtmlToken(LC(' ') + token.text.mid(name.size())));
        else
          out.append(LC(' ') + token.text);
      }
      else
        out.append(token);

      name.clear();
    }
    else if (token.type == HtmlToken::EndTag && token.tag == LS("a") && remove) {
      remove = false;
    }
    else
      out.append(token);
  }

  tokens = out;
  return true;
}
Exemple #15
0
void AuthCore::version()
{
  QTextStream out(stdout);
  out << LS("Simple Chat Auth Daemon, version ") << SCHAT_VERSION;
  if (SCHAT_VER_PATH)
    out << LC('.') << SCHAT_VER_PATH;

  out << endl << endl;
  out << SCHAT_COPYRIGHT << LS(", https://schat.me") << endl;
}
Exemple #16
0
void RegionCN470AInitDefaults( InitType_t type )
{
    switch ( type ) {
        case INIT_TYPE_INIT: {
            // Channels
            Channels[0] = ( ChannelParams_t ) CN470A_LC1;
            Channels[1] = ( ChannelParams_t ) CN470A_LC2;
            Channels[2] = ( ChannelParams_t ) CN470A_LC3;
            Channels[3] = ( ChannelParams_t ) CN470A_LC4;
            Channels[4] = ( ChannelParams_t ) CN470A_LC5;
            Channels[5] = ( ChannelParams_t ) CN470A_LC6;
            Channels[6] = ( ChannelParams_t ) CN470A_LC7;
            Channels[7] = ( ChannelParams_t ) CN470A_LC8;

            // Initialize the channels default mask
            ChannelsDefaultMask[0] = LC( 1 ) + LC( 2 ) + LC( 3 ) + LC( 4 ) + LC( 5 ) + LC( 6 ) + LC( 7 ) + LC( 8 ) ;
            // Update the channels mask
            RegionCommonChanMaskCopy( ChannelsMask, ChannelsDefaultMask, 1 );

            //set default freqband = 1A2(No.=1,471.9Mhz)
            NumFreqBand = 1;
            FreqBandNum[0] = 1; //1A2
            scan_mask = 0;

            //save other freqband from mask
            for (uint8_t i = 0; i < 16; i++) {
                if ((get_lora_freqband_mask() & (1 << i)) != 0 && i != 1) {
                    FreqBandNum[NumFreqBand++] = i;
                }
            }
            NextAvailableFreqBandIdx = 0;
            break;
        }
        case INIT_TYPE_RESTORE: {
            // Restore channels default mask
            ChannelsMask[0] |= ChannelsDefaultMask[0];
            break;
        }
        default: {
            break;
        }
    }
}
Exemple #17
0
ProfileField::ProfileField(const QString &field, QWidget *parent)
  : QWidget(parent)
  , m_field(field)
{
  m_label = new QLabel(Profile::translate(field) + LC(':'), this);

  connect(ChatNotify::i(), SIGNAL(notify(Notify)), SLOT(notify(Notify)));

  QTimer::singleShot(0, this, SLOT(reload()));
}
Exemple #18
0
void QuickScan_Email(void)
{
    int     FoundMsg  = FALSE;
    int	    i;
    char    temp[81];

    iLineCount = 2;
    WhosDoingWhat(READ_POST, NULL);

    if (EmailBase.Total == 0) {
	Enter(1);
	/* There are no messages in this area. */
	pout(WHITE, BLACK, (char *) Language(205));
	Enter(2);
	sleep(3);
	return;
    }

    clear(); 
    /* #    From                  To                       Subject */
    poutCR(YELLOW, BLUE, (char *) Language(220));

    if (Msg_Open(sMailpath)) {
	for (i = EmailBase.Lowest; i <= EmailBase.Highest; i++) {
	    if (Msg_ReadHeader(i)) {
                                
		snprintf(temp, 81, "%-6u", Msg.Id);
		pout(WHITE, BLACK, temp);
		snprintf(temp, 81, "%s ", padleft(Msg.From, 20, ' '));
		pout(CYAN, BLACK, temp);

		snprintf(temp, 81, "%s ", padleft(Msg.To, 20, ' '));
		pout(GREEN, BLACK, temp);
		snprintf(temp, 81, "%s", padleft(Msg.Subject, 31, ' '));
		pout(MAGENTA, BLACK, temp);
		Enter(1);
		FoundMsg = TRUE;
		if (LC(1))
		    break;
	    }
	}
	Msg_Close();
    }

    if(!FoundMsg) {
	Enter(1);
	/* There are no messages in this area. */
	pout(LIGHTGREEN, BLACK, (char *) Language(205));
	Enter(2);
	sleep(3);
    }

    iLineCount = 2;
    Pause();
}
Exemple #19
0
void EmoticonsFilter::parse(QList<HtmlToken> &tokens, const QString &text, int pos) const
{
  if (text.isEmpty())
    return;

  if (pos == -1 || m_count > 6) {
    tokens.append(HtmlToken(text));
    return;
  }

  if (pos < text.size() - 1 && text.at(pos) == LC(' '))
    pos++;

  // Возможно в этой позиции находится начало смайла.
  if (m_emoticons->index().contains(text.at(pos))) {
    QString t = m_emoticons->find(text, pos);

    // Если текст не пустой, смайл найден.
    if (!t.isEmpty()) {

      // Смайл находится в конце строки.
      if (pos + t.size() == text.size()) {
        if (pos)
          tokens.append(HtmlToken(text.left(pos)));

        make(tokens, t);
        return;
      }
      // Смайл находится в внутри строки и содержит после себя пробел.
      else if (text.at(pos + t.size()) == LC(' ')) {
        if (pos)
          tokens.append(HtmlToken(text.left(pos)));

        make(tokens, t);
        parse(tokens, text.mid(pos + t.size()));
        return;
      }
    }
  }

  parse(tokens, text, text.indexOf(LC(' '), pos + 1));
}
Exemple #20
0
bool ProfileField::apply(const QVariant &value)
{
  FeedPtr feed = ChatClient::channel()->feed(FEED_NAME_PROFILE, false);
  if (!feed)
    return false;

  if (feed->data().value(m_field) == value)
    return false;

  return ClientFeeds::post(ChatClient::id(), FEED_NAME_PROFILE + LC('/') + m_field, value, Feed::Echo | Feed::Share | Feed::Broadcast);
}
Exemple #21
0
void StackOverflowAuth::tokenReady()
{
  OAUTH_PREPARE_REPLY

  const QByteArray token = QUrlQuery(QUrl(LC('?') + raw)).queryItemValue(LS("access_token")).toUtf8();
  log(NodeLog::InfoLevel, "Token is successfully received");

  QNetworkRequest request(QUrl(LS("https://api.stackexchange.com/2.1/me?order=desc&sort=reputation&site=stackoverflow&access_token=") + token + LS("&key=") + m_provider->publicKey));
  QNetworkReply *reply = m_manager->get(request);
  connect(reply, SIGNAL(finished()), SLOT(dataReady()));
}
Exemple #22
0
// MODIFY THIS FUNCTION
void drawMesh(cgtk::GLSLProgram &program, const MeshVAO &meshVAO)
{
    program.enable();
    // al=1;
globals.program.setUniform1f("u_al",al);
globals.program.setUniform1f("u_dl",dl);
globals.program.setUniform1f("u_sl",sl);
globals.program.setUniform1f("u_gamma",gam);
globals.program.setUniform1f("u_invert",inv);
// globals.program.setUniform1f("u_zoom",zoom);


    // Define the model, view, and projection matrices here
    glm::mat4 model = glm::mat4(1.0f);
glm::mat4 view = glm::lookAt(glm::vec3(0.0f,0.0f,6.0f),
    				 glm::vec3(0.0f,1.0f,0.0f),
    				 glm::vec3(0.0f,0.0f,1.0f));
    glm::mat4 projection = glm::perspective(zoom*10.5f,1.0f,3.0f,8.0f);
    // Construct the ModelViewProjection, ModelView, and normal
    // matrices here and pass them as uniform variables to the shader
    // program
	glm::mat4 MV = view*model;
	globals.program.setUniformMatrix4f("u_MV",MV);

	glm::mat4 MVP = projection*view*model;
	globals.program.setUniformMatrix4f("u_MVP",MVP);

    glm::mat4 NM = glm::transpose(glm::inverse(MV));
    globals.program.setUniformMatrix4f("u_NM", NM);
   

    // Set up the light source and material properties and pass them
    // as uniform variables to the shader program, along with the
    // flags (uniform int variables) used for toggling on/off
    // different parts of the rendering
    glm::vec3 LP(0.0,0.0,8.0);
    globals.program.setUniform3f("u_LP", LP);
    glm::vec3 LC(1.0,1.0,1.0);
    globals.program.setUniform3f("u_LC", LC);
    glm::vec3 DC(1.0,1.0,0);
    glm::vec3 AC=glm::vec3(1.0,0,1.0);
    glm::vec3 SC(0,1.0,1.0);
    globals.program.setUniform3f("u_DC", DC);
    globals.program.setUniform3f("u_AC", AC);
    globals.program.setUniform3f("u_SC", SC);
    float SP = 1.0;
//    globals.program.setUniform1f("u_SP", SP);

    glBindVertexArray(meshVAO.vao);
    glDrawElements(GL_TRIANGLES, meshVAO.numIndices, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

    program.disable();
}
Exemple #23
0
void OsInfo::init()
{
  QString os;
  m_type = Linux;

  detectLinux(os, m_type);
  if (os.isEmpty()) {
    utsname buf;
    if (uname(&buf) != -1) {
      os.append(buf.sysname).append(LC(' '));
      os.append(buf.release).append(LC(' '));
      os.append(buf.machine);
    }
    else {
      os = LS("Linux");
    }
  }

  m_json.insert(LS("os"), os);
}
Exemple #24
0
void RawFeedsCmd::request(const QString &method, const QByteArray &dest, const QString &body)
{
  NetRequest req;
  req.method  = method;
  req.headers = m_headers;
  m_headers.clear();

  const int index = body.indexOf(LC(' '));
  if (index != -1) {
    req.request = body.left(index);
    req.data    = JSON::parse(body.mid(index + 1).toUtf8());
  }
  else
    req.request = body;

  if (req.request.startsWith(LC('$')))
    req.request.replace(0, 1, ChatId::toBase32(dest));

  m_plugin->add(req.id);
  ClientFeeds::req(req);
}
Exemple #25
0
void ChatCore::crashreport()
{
  const QString path = QApplication::applicationDirPath();

  QDir dir(path);

  const QStringList files = dir.entryList(QStringList(LS("*.dmp")), QDir::Files);
  if (files.isEmpty())
    return;

  QProcess::startDetached(LC('"') + path + LS("/crashreport.exe\""), QStringList(), path);
}
Exemple #26
0
/*!
 * Установка версии в формате "major.minor.patch"
 */
void Ver::setVersion(const QString &version)
{
  QStringList split = version.split(LC('.'));
  if (split.size() > 0)
    m_major = split.at(0).toInt();

  if (split.size() > 1)
    m_minor = split.at(1).toInt();

  if (split.size() > 2)
    m_patch = split.at(2).toInt();
}
Exemple #27
0
/*!
 * Возвращает и при необходимости создаёт путь для хранения файлов сервера.
 *
 * \param id Base32 кодированный идентификатор сервера с опциональным именем авторизационного провайдера.
 */
QString NetworkManager::root(const QByteArray &id) const
{
  const ChatId _id(id.left(ChatId::kEncodedSize));
  if (_id.isNull())
    return QString();

  const QString out = Path::cache() + LC('/') + _id.toString();
  if (!QFile::exists(out))
    QDir().mkpath(out);

  return out;
}
Exemple #28
0
/*!
 * Получение начального и конечного положения тела атрибута \p attr в входящей строке \p tag.
 */
HtmlFilter::Range HtmlFilter::attrBody(const QString &attr, const QString &tag) const
{
  Range body(-1, -1);
  body.first = tag.indexOf(attr + LC('='));
  if (body.first == -1) // атрибут не найден.
    return body;

  body.first = body.first + attr.size() + 2;
  if (tag.size() == body.first) // пустое тело атрибута.
    return Range(-1, -1);

  const QChar c = tag.at(body.first - 1);
  if (c != LC('\'') && c != LC('"')) // не допустимый символ начала тела.
    return Range(-1, -1);

  body.second = tag.indexOf(c, body.first);
  if (body.second == -1 || body.first == body.second) // конец тела не найден или пустое тело.
    return Range(-1, -1);

  return body;
}
Exemple #29
0
// .. c:function::
void
ch_rm_free(ch_remote_t* remote)
//    :noindex:
//
//    see: :c:func:`ch_rm_free`
//
// .. code-block:: cpp
//
{
    LC(remote->chirp, "Remote freed", "ch_remote_t:%p", remote);
    if (remote->noop != NULL) {
        ch_free(remote->noop);
    }
    ch_free(remote);
}
Exemple #30
0
QString PlainTextFilter::filter(const QString &text)
{
  QString out = text;

  out.replace(LC('\n'), QString());
  out.replace(LS("</p>"), LS("\n"), Qt::CaseInsensitive);
  out.replace(LS("<br />"), LS("\n"), Qt::CaseInsensitive);

  removeTag(out, LS("style"));
  removeTag(out, LS("script"));

  int lt = 0;
  int gt = 0;
  forever {
    lt = out.indexOf(LC('<'), lt);
    if (lt == -1)
      break;

    gt = out.indexOf(LC('>'), lt);
    if (gt == -1) {
      out.remove(lt, out.size() - lt);
      break;
    }

    out.remove(lt, gt - lt + 1);
  }

  out.replace(LS("&gt;"),         LS(">"));
  out.replace(LS("&lt;"),         LS("<"));
  out.replace(LS("&quot;"),       LS("\""));
  out.replace(LS("&nbsp;"),       LS(" "));
  out.replace(LS("&amp;"),        LS("&"));
  out.replace(QChar(QChar::Nbsp), LS(" "));
  out = out.trimmed();
  return out;
}